razorpay 1.2.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f1342dbfd634ead754a60f675870429894fdab71
4
- data.tar.gz: f3b91327653aa94ac1e19e684223ffc9e7e890c7
3
+ metadata.gz: dc80169863413c4b51ebcd5dbc7a163a48c35a06
4
+ data.tar.gz: 73f38b5fafff2e2933c112a54e7d3e418f9440a1
5
5
  SHA512:
6
- metadata.gz: 977fee36b31a1d7e44d0679eddf5593702387974a46438613383ea9f9588f84c3e9dbda7d6a05f719f22086a206ab5e07918eb474be04822b144cfb329d45bbd
7
- data.tar.gz: 3e32025de35f357144a6da06a492e42c9efe20e93ef546cfc55bafb607dc4df6a3d9d13fcbb01f656a6ac6cbeb018d108c8e674b5e5f78956247d334dd871305
6
+ metadata.gz: 1740e3ece8cbdd0b3af137d861c8fecbeb880688df7f971d6780cd81bfac40a3341625e8f5d62dca1842f6a1a9015598c25737778fc0bd241accb0de8b4e7d52
7
+ data.tar.gz: 56c6cbba384b3035cc9cb08a5d1ecdf5ca09401e0af7d1335d90e1a37962f455efaa9d5fb318af7f4acab7df690e1a00f29d11ee9b8733cc5f13f7d92733c4e5
data/.travis.yml CHANGED
@@ -1,6 +1,10 @@
1
- language: ruby # Auto-detected as well
1
+ language: ruby
2
2
  rvm:
3
- - "2.0.0"
4
3
  - "2.1.10"
5
4
  - "2.2.6"
6
5
  - "2.3.3"
6
+ - "2.4.0"
7
+ before_install: gem update --system
8
+ script:
9
+ - bundle exec rake test
10
+ - bundle exec rake rubocop
data/CHANGELOG CHANGED
@@ -2,9 +2,25 @@
2
2
 
3
3
  Changelog for Razorpay-Ruby SDK.
4
4
 
5
+ ## Unreleased
6
+
7
+ ## [2.0.0] - 2016-03-02
8
+ ### Added
9
+ - Adds `require` for all Razorpay supported entities
10
+ - All entity objects now throw `NoMethodError` instead of `NameError` if the attribute doesn't exist
11
+ - Adds customer edit API
12
+ - Adds card fetch API
13
+ - Adds custom header support
14
+ - Adds constant time signature verification API for payments and webhooks
15
+ - Adds payment capture-without-fetch API
16
+ - Enables warnings for tests
17
+ - Removes circular `require` calls
18
+ - Adds rake test groups
19
+
5
20
  ## [1.2.1] - 2016-12-22
6
21
  ### Changed
7
22
  - Drops ArgumentError checks for local validation. Rely on server side checks instead.
23
+
8
24
  ### Added
9
25
  - Support for customers and invoices API
10
26
  - Loads Order class by default.
@@ -30,7 +46,8 @@ Changelog for Razorpay-Ruby SDK.
30
46
  ### Added
31
47
  - Initial Release
32
48
 
33
- [Unreleased]: https://github.com/razorpay/razorpay-ruby/compare/1.2.1...HEAD
49
+ [Unreleased]: https://github.com/razorpay/razorpay-ruby/compare/2.0.0...HEAD
50
+ [2.0.0]: https://github.com/razorpay/razorpay-ruby/compare/1.2.1...2.0.0
34
51
  [1.2.1]: https://github.com/razorpay/razorpay-ruby/compare/1.2.0...1.2.1
35
52
  [1.2.0]: https://github.com/razorpay/razorpay-ruby/compare/1.1.0...1.2.0
36
53
  [1.1.0]: https://github.com/razorpay/razorpay-ruby/compare/1.0.3...1.1.0
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Razorpay Ruby bindings
2
2
 
3
- [![Build Status](https://travis-ci.org/razorpay/razorpay-ruby.svg?branch=master)](https://travis-ci.org/razorpay/razorpay-ruby) [![Gem Version](https://badge.fury.io/rb/razorpay.svg)](http://badge.fury.io/rb/razorpay) [![License](http://img.shields.io/:license-mit-blue.svg)](http://doge.mit-license.org)
3
+ [![Build Status](https://travis-ci.org/razorpay/razorpay-ruby.svg?branch=master)](https://travis-ci.org/razorpay/razorpay-ruby) [![Gem Version](https://badge.fury.io/rb/razorpay.svg)](http://badge.fury.io/rb/razorpay) [![Coverage Status](https://coveralls.io/repos/github/Razorpay/razorpay-ruby/badge.svg?branch=master)](https://coveralls.io/github/Razorpay/razorpay-ruby?branch=master) [![License](http://img.shields.io/:license-mit-blue.svg)](http://doge.mit-license.org)
4
4
 
5
5
  This is the base ruby gem for interacting with the Razorpay API. This is primarily meant for merchants who wish to perform interactions with the Razorpay API programatically.
6
6
 
@@ -30,6 +30,11 @@ Next, you need to setup your key and secret using the following:
30
30
  Razorpay.setup("merchant_key_id", "merchant_key_secret")
31
31
  ```
32
32
 
33
+ You can set customer headers for your requests using the following:
34
+ ```rb
35
+ Razorpay.headers = {"CUSTOM_APP_HEADER" => "CUSTOM_VALUE"}
36
+ ```
37
+
33
38
  You can find your API keys at <https://dashboard.razorpay.com/#/app/keys>.
34
39
 
35
40
  If you are using rails, the right place to do this might be `config/initializers/razorpay.rb`.
@@ -37,7 +42,7 @@ If you are using rails, the right place to do this might be `config/initializers
37
42
  The most common construct is capturing a payment, which you do via the following:
38
43
 
39
44
  ```rb
40
- Razorpay::Payment.fetch("pay-ment_id").capture({amount:500})
45
+ Razorpay::Payment.fetch("payment_id").capture({amount:500})
41
46
  # Note that the amount should come from your session, so as to verify
42
47
  # that the purchase was correctly done and not tampered
43
48
  ```
@@ -46,6 +51,13 @@ You can handle refunds using the following constructs:
46
51
 
47
52
  ```rb
48
53
  Razorpay::Payment.fetch("payment_id").refund({amount:500})
54
+ refunds = Razorpay::Payment.fetch("payment_id").refunds
55
+ ```
56
+
57
+ Refunds can also be handled without fetching payments:
58
+ ```rb
59
+ refund = Razorpay::Refund.create(payment_id:"payment_id")
60
+ Razorpay::Refund.fetch(refund.id)
49
61
  ```
50
62
 
51
63
  For other applications (such as fetching payments and refunds),
@@ -70,11 +82,38 @@ puts order.amount
70
82
 
71
83
  # Fetching payments corresponding to an order
72
84
  payments = order.payments
85
+ ```
73
86
 
87
+ ### Verification
88
+ You can use the Utility class to verify the signature received in response to a payment made using Orders API
89
+ ```rb
90
+ puts payment_response
91
+ # {
92
+ # :razorpay_order_id => "fake_order_id",
93
+ # :razorpay_payment_id => "fake_payment_id",
94
+ # :razorpay_signature => "signature"
95
+ # }
96
+ Razorpay::Utility.verify_payment_signature(payment_response)
97
+ ```
98
+
99
+ ### Customers
100
+ ```rb
74
101
  # Create a customer
75
102
  customer = Razorpay::Customer.create email: 'test@razorpay.com', contact: '9876543210'
76
103
  puts customer.id #cust_6vRXClWqnLhV14
104
+ ```
105
+
106
+ ### Cards
107
+ ```rb
108
+ # Fetch a card
109
+ card = Razorpay::Card.fetch('card_7EZLhWkDt05n7V')
110
+ puts card.network #VISA
111
+ ```
77
112
 
113
+ You can find invoices API documentation at <https://docs.razorpay.com/v1/page/cards>.
114
+
115
+ ### Invoices
116
+ ```rb
78
117
  # Creating an invoice
79
118
  invoice = Razorpay::Invoice.create customer_id: customer.id, amount: 100, currency: 'INR', description: 'Test description', type: 'link'
80
119
  ```
data/Rakefile CHANGED
@@ -1,9 +1,24 @@
1
1
  require 'rake/testtask'
2
+ require 'rubocop/rake_task'
2
3
 
3
4
  Rake::TestTask.new do |t|
4
5
  t.libs << 'test'
6
+ t.warning = true
5
7
  t.pattern = 'test/razorpay/test_*.rb'
6
8
  end
7
9
 
8
10
  desc 'Run tests'
9
- task default: :test
11
+ task default: [:test, :rubocop]
12
+
13
+ desc 'Run rubocop'
14
+ task :rubocop do
15
+ RuboCop::RakeTask.new
16
+ end
17
+
18
+ FileList['test/razorpay/test_*.rb'].each do |file|
19
+ group = File.basename(file, '.rb').split('_').last.to_sym
20
+ Rake::TestTask.new(group) do |t|
21
+ t.libs << 'test'
22
+ t.test_files = [file]
23
+ end
24
+ end
data/lib/razorpay.rb CHANGED
@@ -1,14 +1,25 @@
1
- require 'razorpay/constants'
2
- require 'razorpay/payment'
1
+ require 'razorpay/card'
3
2
  require 'razorpay/order'
3
+ require 'razorpay/errors'
4
+ require 'razorpay/refund'
5
+ require 'razorpay/invoice'
6
+ require 'razorpay/payment'
7
+ require 'razorpay/utility'
8
+ require 'razorpay/customer'
9
+ require 'razorpay/constants'
10
+ require 'razorpay/collection'
4
11
 
5
12
  # Base Razorpay module
6
13
  module Razorpay
7
14
  class << self
8
- attr_accessor :auth
15
+ attr_accessor :auth, :custom_headers
9
16
  end
10
17
 
11
18
  def self.setup(key_id, key_secret)
12
19
  self.auth = { username: key_id, password: key_secret }
13
20
  end
21
+
22
+ def self.headers=(headers = {})
23
+ self.custom_headers = headers
24
+ end
14
25
  end
@@ -0,0 +1,17 @@
1
+ require 'razorpay/request'
2
+ require 'razorpay/entity'
3
+
4
+ module Razorpay
5
+ # Card API allows you to fetch cards
6
+ # saved with Razorpay
7
+ # Docs: https://docs.razorpay.com/v1/page/cards
8
+ class Card < Entity
9
+ def self.request
10
+ Razorpay::Request.new('cards')
11
+ end
12
+
13
+ def self.fetch(id)
14
+ request.fetch id
15
+ end
16
+ end
17
+ end
@@ -2,5 +2,5 @@
2
2
  module Razorpay
3
3
  BASE_URI = 'https://api.razorpay.com/v1/'.freeze
4
4
  TEST_URL = 'https://api.razorpay.com/'.freeze
5
- VERSION = '1.2.1'.freeze
5
+ VERSION = '2.0.0'.freeze
6
6
  end
@@ -2,7 +2,7 @@ require 'razorpay/request'
2
2
  require 'razorpay/entity'
3
3
 
4
4
  module Razorpay
5
- # Customer API allows you to create customer IDs on Razorpay
5
+ # Customer API allows you to create and fetch customers on Razorpay
6
6
  class Customer < Entity
7
7
  def self.request
8
8
  Razorpay::Request.new('customers')
@@ -11,5 +11,17 @@ module Razorpay
11
11
  def self.create(options)
12
12
  request.create options
13
13
  end
14
+
15
+ def self.fetch(id)
16
+ request.fetch id
17
+ end
18
+
19
+ def self.edit(id, options = {})
20
+ request.put id, options
21
+ end
22
+
23
+ def self.all(options = {})
24
+ request.all options
25
+ end
14
26
  end
15
27
  end
@@ -13,9 +13,15 @@ module Razorpay
13
13
  # the @attributes hash as the source, instead of
14
14
  # instance variables
15
15
  def method_missing(name)
16
- name = name.to_s
17
- raise NameError, "No such data member: #{name}" unless @attributes.key? name
18
- @attributes[name]
16
+ if @attributes.key? name.to_s
17
+ @attributes[name.to_s]
18
+ else
19
+ super
20
+ end
21
+ end
22
+
23
+ def respond_to_missing?(method_name, include_private = false)
24
+ @attributes.key?(method_name.to_s) || super
19
25
  end
20
26
 
21
27
  # Public: Convert the Entity object to JSON
@@ -19,19 +19,22 @@ module Razorpay
19
19
  request.all options
20
20
  end
21
21
 
22
- def refund(options = {})
23
- self.class.request.post "#{id}/refund", options
22
+ def self.capture(id, options)
23
+ request.post "#{id}/capture", options
24
24
  end
25
25
 
26
- def refunds
27
- # This needs to be a string, not a symbol
28
- Refund.new('payment_id' => id)
26
+ def refund(options = {})
27
+ self.class.request.post "#{id}/refund", options
29
28
  end
30
29
 
31
30
  def capture(options)
32
31
  self.class.request.post "#{id}/capture", options
33
32
  end
34
33
 
34
+ def refunds
35
+ self.class.request.get "#{id}/refunds"
36
+ end
37
+
35
38
  def method
36
39
  method_missing(:method)
37
40
  end
@@ -1,22 +1,23 @@
1
- require 'razorpay'
2
1
  require 'razorpay/request'
3
2
  require 'razorpay/entity'
4
3
 
5
4
  module Razorpay
6
5
  # Refund class handles all refund objects
7
6
  class Refund < Entity
8
- def initialize(data)
9
- super
10
- @request = Razorpay::Request.new("payments/#{payment_id}/refunds")
7
+ def self.request
8
+ Razorpay::Request.new('refunds')
11
9
  end
12
10
 
13
- def all(options = {})
14
- # We receive an array of item hashes
15
- @request.all options
11
+ def self.create(options)
12
+ request.create options
16
13
  end
17
14
 
18
- def fetch(id)
19
- @request.fetch id
15
+ def self.all(options = {})
16
+ request.all options
17
+ end
18
+
19
+ def self.fetch(id)
20
+ request.fetch id
20
21
  end
21
22
  end
22
23
  end
@@ -1,4 +1,4 @@
1
- require 'razorpay'
1
+ require 'razorpay/constants'
2
2
  require 'httparty'
3
3
 
4
4
  module Razorpay
@@ -13,12 +13,16 @@ module Razorpay
13
13
  def initialize(entity_name)
14
14
  self.class.base_uri(Razorpay::BASE_URI)
15
15
  @entity_name = entity_name
16
+ custom_headers = Razorpay.custom_headers || {}
17
+ predefined_headers = {
18
+ 'User-Agent' => "Razorpay-Ruby/#{Razorpay::VERSION}"
19
+ }
20
+ # Order is important to give precedence to predefined headers
21
+ headers = custom_headers.merge(predefined_headers)
16
22
  @options = {
17
23
  basic_auth: Razorpay.auth,
18
24
  timeout: 30,
19
- headers: {
20
- 'User-Agent' => "Razorpay-Ruby/#{Razorpay::VERSION}"
21
- }
25
+ headers: headers
22
26
  }
23
27
  end
24
28
 
@@ -34,6 +38,14 @@ module Razorpay
34
38
  request :post, "/#{@entity_name}/#{url}", data
35
39
  end
36
40
 
41
+ def get(url)
42
+ request :get, "/#{@entity_name}/#{url}"
43
+ end
44
+
45
+ def put(id, data = {})
46
+ request :put, "/#{@entity_name}/#{id}", data
47
+ end
48
+
37
49
  def create(data)
38
50
  request :post, "/#{@entity_name}", data
39
51
  end
@@ -44,6 +56,8 @@ module Razorpay
44
56
  @options[:query] = data
45
57
  when :post
46
58
  @options[:body] = data
59
+ when :put
60
+ @options[:body] = data
47
61
  end
48
62
  create_instance self.class.send(method, url, @options)
49
63
  end
@@ -75,15 +89,15 @@ module Razorpay
75
89
 
76
90
  def raise_error(error, status)
77
91
  # Get the error class name, require it and instantiate an error
78
- require "razorpay/errors/#{error['code'].downcase}"
79
92
  class_name = error['code'].split('_').map(&:capitalize).join('')
80
93
  args = [error['code'], status]
81
94
  args.push error['field'] if error.key?('field')
82
95
  klass =
83
96
  begin
97
+ require "razorpay/errors/#{error['code'].downcase}"
84
98
  Razorpay.const_get(class_name)
85
99
  # We got an unknown error, cast it to Error for now
86
- rescue NameError
100
+ rescue NameError, LoadError
87
101
  Razorpay::Error
88
102
  end
89
103
  raise klass.new(*args), error['description']
@@ -0,0 +1,49 @@
1
+ require 'openssl'
2
+
3
+ module Razorpay
4
+ # Helper functions are defined here
5
+ class Utility
6
+ def self.verify_payment_signature(attributes)
7
+ signature = attributes[:razorpay_signature]
8
+ order_id = attributes[:razorpay_order_id]
9
+ payment_id = attributes[:razorpay_payment_id]
10
+
11
+ data = [order_id, payment_id].join '|'
12
+
13
+ verify_signature(signature, data)
14
+ end
15
+
16
+ def self.verify_webhook_signature(signature, body)
17
+ verify_signature(signature, body)
18
+ end
19
+
20
+ class << self
21
+ private
22
+
23
+ def verify_signature(signature, data)
24
+ secret = Razorpay.auth[:password]
25
+
26
+ expected_signature = OpenSSL::HMAC.hexdigest('SHA256', secret, data)
27
+
28
+ verified = secure_compare(expected_signature, signature)
29
+
30
+ raise SecurityError, 'Signature verification failed' unless verified
31
+ end
32
+
33
+ def secure_compare(a, b)
34
+ return false unless a.bytesize == b.bytesize
35
+
36
+ l = a.unpack('C*')
37
+ r = 0
38
+ i = -1
39
+
40
+ b.each_byte do |v|
41
+ i += 1
42
+ r |= v ^ l[i]
43
+ end
44
+
45
+ r.zero?
46
+ end
47
+ end
48
+ end
49
+ end
@@ -18,9 +18,10 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(/^(test|spec|features)/)
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_development_dependency 'rake', '~> 10.5'
22
- spec.add_development_dependency 'minitest', '~> 5.8'
23
- spec.add_development_dependency 'webmock', '~> 1.24'
24
- spec.add_development_dependency 'simplecov', '~> 0.11'
25
- spec.add_dependency 'httparty', '~> 0.13'
21
+ spec.add_development_dependency 'rake', '~> 12.0'
22
+ spec.add_development_dependency 'minitest', '~> 5.10'
23
+ spec.add_development_dependency 'webmock', '~> 2.3'
24
+ spec.add_development_dependency 'coveralls', '~> 0.8'
25
+ spec.add_development_dependency 'rubocop', '~> 0.47'
26
+ spec.add_dependency 'httparty', '~> 0.14'
26
27
  end
@@ -0,0 +1,22 @@
1
+ {
2
+ "entity": "collection",
3
+ "count": 2,
4
+ "items": [
5
+ {
6
+ "id": "cust_6vRXClWqnLhV14",
7
+ "email": "test@razorpay.com",
8
+ "contact": "9876543210",
9
+ "notes": [],
10
+ "created_at": 1482299274,
11
+ "entity": "customer"
12
+ },
13
+ {
14
+ "id": "cust_50smJrkZ4Qb0HJ",
15
+ "email": "test2@razorpay.com",
16
+ "contact": "9876543211",
17
+ "notes": [],
18
+ "created_at": 1482299274,
19
+ "entity": "customer"
20
+ }
21
+ ]
22
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "id": "card_7EZLhWkDt05n7V",
3
+ "entity": "card",
4
+ "name": "Fake customer name",
5
+ "last4": "4321",
6
+ "network": "Visa",
7
+ "type": "debit",
8
+ "international": false
9
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "id": "cust_6vRXClWqnLhV14",
3
+ "email": "test.edit@razorpay.com",
4
+ "contact": "9876543210",
5
+ "notes": [],
6
+ "created_at": 1482299274,
7
+ "entity": "customer"
8
+ }
@@ -0,0 +1,40 @@
1
+ {
2
+ "event": "payment.authorized",
3
+ "entity": "event",
4
+ "contains": [
5
+ "payment"
6
+ ],
7
+ "payload": {
8
+ "payment": {
9
+ "entity": {
10
+ "id": "pay_6koWN7bvxujzxM",
11
+ "entity": "payment",
12
+ "amount": 1000000,
13
+ "currency": "INR",
14
+ "status": "captured",
15
+ "order_id": "order_100000000order",
16
+ "international": false,
17
+ "method": "card",
18
+ "amount_refunded": 0,
19
+ "refund_status": null,
20
+ "captured": true,
21
+ "description": "random description",
22
+ "card_id": "card_6koWNAT6LASUqy",
23
+ "bank": null,
24
+ "wallet": null,
25
+ "vpa": null,
26
+ "email": "a@b.com",
27
+ "contact": "+919999999999",
28
+ "notes": {
29
+ "merchant_order_id": "random order id"
30
+ },
31
+ "fee": 23000,
32
+ "service_tax": 3000,
33
+ "error_code": null,
34
+ "error_description": null,
35
+ "created_at": 1479978483
36
+ }
37
+ }
38
+ },
39
+ "created_at": 1400826760
40
+ }
@@ -1,5 +1,5 @@
1
1
  {
2
- "count": 2,
2
+ "count": 3,
3
3
  "entity": "collection",
4
4
  "items": [
5
5
  {
@@ -17,6 +17,14 @@
17
17
  "currency": "INR",
18
18
  "payment_id": "fake_payment_id",
19
19
  "created_at": 1500826750
20
+ },
21
+ {
22
+ "id": "rfnd_6vRZmJu7EPEMY0",
23
+ "entity": "refund",
24
+ "amount": 200,
25
+ "currency": "INR",
26
+ "payment_id": "fake_payment_id_2",
27
+ "created_at": 1500826750
20
28
  }
21
29
  ]
22
- }
30
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "count": 2,
3
+ "entity": "collection",
4
+ "items": [
5
+ {
6
+ "id": "rfnd_AABBdHIieexn5c",
7
+ "entity": "refund",
8
+ "amount": 100,
9
+ "currency": "INR",
10
+ "payment_id": "fake_payment_id",
11
+ "created_at": 1500826750
12
+ },
13
+ {
14
+ "id": "rfnd_19btGlBig6xZ2f",
15
+ "entity": "refund",
16
+ "amount": 100,
17
+ "currency": "INR",
18
+ "payment_id": "fake_payment_id",
19
+ "created_at": 1500826750
20
+ }
21
+ ]
22
+ }
@@ -0,0 +1,23 @@
1
+ require 'test_helper'
2
+
3
+ module Razorpay
4
+ # Tests for Razorpay::Card
5
+ class RazorpayCardTest < Minitest::Test
6
+ def setup
7
+ @card_id = 'card_7EZLhWkDt05n7V'
8
+
9
+ # Any request that ends with cards/card_id
10
+ stub_get(%r{cards/#{@card_id}$}, 'fake_card')
11
+ end
12
+
13
+ def test_card_should_be_defined
14
+ refute_nil Razorpay::Card
15
+ end
16
+
17
+ def test_cards_should_be_fetched
18
+ card = Razorpay::Card.fetch(@card_id)
19
+ assert_instance_of Razorpay::Card, card, 'card not an instance of Razorpay::Card class'
20
+ assert_equal @card_id, card.id, 'card IDs do not match'
21
+ end
22
+ end
23
+ end
@@ -1,6 +1,4 @@
1
1
  require 'test_helper'
2
- require 'razorpay/customer'
3
- require 'razorpay/collection'
4
2
 
5
3
  module Razorpay
6
4
  # Tests for Razorpay::Customer
@@ -10,6 +8,7 @@ module Razorpay
10
8
 
11
9
  # Any request that ends with customers/customer_id
12
10
  stub_get(%r{customers/#{@customer_id}$}, 'fake_customer')
11
+ stub_get(/customers$/, 'customer_collection')
13
12
  end
14
13
 
15
14
  def test_customer_should_be_defined
@@ -23,5 +22,24 @@ module Razorpay
23
22
  assert_equal 'test@razorpay.com', customer.email
24
23
  assert_equal '9876543210', customer.contact
25
24
  end
25
+
26
+ def test_edit_customer
27
+ new_email = 'test.edit@razorpay.com'
28
+ stub_put(%r{customers/#{@customer_id}$}, 'fake_customer_edited', "email=#{new_email}")
29
+ customer = Razorpay::Customer.edit(@customer_id, "email=#{new_email}")
30
+ assert_instance_of Razorpay::Customer, customer
31
+ assert_equal customer.email, new_email
32
+ end
33
+
34
+ def test_fetch_all_customers
35
+ customers = Razorpay::Customer.all
36
+ assert_instance_of Razorpay::Collection, customers
37
+ end
38
+
39
+ def test_fetch_specific_customer
40
+ customer = Razorpay::Customer.fetch(@customer_id)
41
+ assert_instance_of Razorpay::Customer, customer
42
+ assert_equal customer.id, @customer_id
43
+ end
26
44
  end
27
45
  end
@@ -1,5 +1,5 @@
1
1
  require 'test_helper'
2
- require 'razorpay/entity'
2
+ require 'ostruct'
3
3
 
4
4
  module Razorpay
5
5
  # Tests for Razorpay::Entity
@@ -9,6 +9,29 @@ module Razorpay
9
9
  @entity = Entity.new(@hash)
10
10
  end
11
11
 
12
+ def test_create_instance
13
+ res = OpenStruct.new(parsed_response: { 'entity' => 'non_existent_entity' })
14
+ entity = Razorpay::Request.new('dummy').create_instance(res)
15
+ assert_instance_of Razorpay::Entity, entity
16
+ end
17
+
18
+ def test_raise_error
19
+ error = { 'code' => 'NON_EXISTENT_ERROR', 'description' => 'Unknown error' }
20
+ assert_raises(Razorpay::Error) { Razorpay::Request.new('dummy').raise_error(error, 500) }
21
+ end
22
+
23
+ def test_respond_to_missing_method
24
+ order_id = 'order_50sX9hGHZJvjjI'
25
+ stub_get(%r{orders/#{order_id}$}, 'fake_order')
26
+ order = Razorpay::Order.fetch(order_id)
27
+ assert_equal order.respond_to?(:non_existent_method), false
28
+
29
+ payment_id = 'fake_payment_id'
30
+ stub_get(%r{payments/#{payment_id}$}, 'fake_payment')
31
+ payment = Razorpay::Payment.fetch(payment_id)
32
+ assert_equal payment.respond_to?(:method), true
33
+ end
34
+
12
35
  def test_attribute_get
13
36
  assert_equal @hash['a'], @entity.a
14
37
  end
@@ -18,7 +41,7 @@ module Razorpay
18
41
  end
19
42
 
20
43
  def test_invalid_attribute_get
21
- assert_raises(NameError, 'It must raise a NameError on invalid attribute') { @entity.b }
44
+ assert_raises(NoMethodError, 'It must raise a NoMethodError on invalid attribute') { @entity.b }
22
45
  end
23
46
  end
24
47
  end
@@ -1,6 +1,4 @@
1
1
  require 'test_helper'
2
- require 'razorpay/entity'
3
- require 'razorpay/errors/bad_request_error'
4
2
 
5
3
  module Razorpay
6
4
  # Tests for Razorpay::Entity
@@ -1,6 +1,4 @@
1
1
  require 'test_helper'
2
- require 'razorpay/invoice'
3
- require 'razorpay/collection'
4
2
 
5
3
  module Razorpay
6
4
  # Tests for Razorpay::Invoice
@@ -17,8 +15,12 @@ module Razorpay
17
15
  end
18
16
 
19
17
  def test_invoice_should_be_created
20
- stub_post(/invoices$/, 'fake_invoice', 'customer_id=cust_6vRXClWqnLhV14&amount=100&currency=INR&description=Test%20description&type=link')
21
- invoice = Razorpay::Invoice.create customer_id: 'cust_6vRXClWqnLhV14', amount: 100, currency: 'INR', description: 'Test description', type: 'link'
18
+ stub_post(/invoices$/, 'fake_invoice', 'customer_id=cust_6vRXClWqnLhV14&'\
19
+ 'amount=100&currency=INR&description=Test%20description&type=link')
20
+ invoice = Razorpay::Invoice.create customer_id: 'cust_6vRXClWqnLhV14',
21
+ amount: 100, currency: 'INR',
22
+ description: 'Test description',
23
+ type: 'link'
22
24
 
23
25
  assert_equal 'cust_6vRXClWqnLhV14', invoice.customer_id
24
26
  assert_equal 100, invoice.amount
@@ -1,6 +1,4 @@
1
1
  require 'test_helper'
2
- require 'razorpay/order'
3
- require 'razorpay/collection'
4
2
 
5
3
  module Razorpay
6
4
  # Tests for Razorpay::Order
@@ -1,6 +1,4 @@
1
1
  require 'test_helper'
2
- require 'razorpay/payment'
3
- require 'razorpay/collection'
4
2
 
5
3
  module Razorpay
6
4
  # Tests for Razorpay::Payment
@@ -60,5 +58,11 @@ module Razorpay
60
58
  payment = payment.capture(amount: 5100)
61
59
  assert_equal 'captured', payment.status
62
60
  end
61
+
62
+ def test_payment_capture_without_fetch
63
+ stub_post(%r{payments/#{@payment_id}/capture$}, 'fake_captured_payment', 'amount=5100')
64
+ payment = Razorpay::Payment.capture(@payment_id, amount: 5100)
65
+ assert_equal 'captured', payment.status
66
+ end
63
67
  end
64
68
  end
@@ -1,7 +1,5 @@
1
1
  require 'test_helper'
2
- require 'razorpay'
3
2
  require 'webmock'
4
- require 'test_helper'
5
3
 
6
4
  module Razorpay
7
5
  # Tests for Razorpay
@@ -19,6 +17,19 @@ module Razorpay
19
17
  assert_equal auth, Razorpay.auth
20
18
  end
21
19
 
20
+ def test_custom_header
21
+ custom_headers = { 'key' => 'value' }
22
+ stub_get(/$/, 'hello_response')
23
+ Razorpay.headers = custom_headers
24
+ Razorpay::Request.new('dummy').make_test_request
25
+ user_agent = "Razorpay-Ruby/#{Razorpay::VERSION}"
26
+ headers = { 'User-Agent' => user_agent, 'Authorization' => 'Basic a2V5X2lkOmtleV9zZWNyZXQ=' }
27
+ headers = headers.merge(custom_headers)
28
+ assert_requested :get, 'https://api.razorpay.com/',
29
+ headers: headers,
30
+ times: 1
31
+ end
32
+
22
33
  # We make a request to the / endpoint to test SSL support
23
34
  def test_sample_request
24
35
  WebMock.allow_net_connect!
@@ -33,8 +44,9 @@ module Razorpay
33
44
  stub_get(/$/, 'hello_response')
34
45
  Razorpay::Request.new('dummy').make_test_request
35
46
  user_agent = "Razorpay-Ruby/#{Razorpay::VERSION}"
36
- assert_requested :get, 'https://key_id:key_secret@api.razorpay.com/',
37
- headers: { 'User-Agent' => user_agent },
47
+ headers = { 'User-Agent' => user_agent, 'Authorization' => 'Basic a2V5X2lkOmtleV9zZWNyZXQ=' }
48
+ assert_requested :get, 'https://api.razorpay.com/',
49
+ headers: headers,
38
50
  times: 1
39
51
  end
40
52
  end
@@ -1,31 +1,42 @@
1
1
  require 'test_helper'
2
- require 'razorpay/payment'
3
- require 'razorpay/refund'
4
2
 
5
3
  module Razorpay
6
4
  # Tests for Razorpay::Refund
7
5
  class RazorpayRefundTest < Minitest::Test
8
6
  def setup
9
7
  @payment_id = 'fake_payment_id'
10
- stub_get(%r{payments\/#{Regexp.quote(@payment_id)}$}, 'fake_payment')
8
+ stub_get(%r{payments/#{@payment_id}$}, 'fake_payment')
9
+ @refund_id = 'fake_refund_id'
10
+ stub_get(%r{refunds/#{@refund_id}$}, 'fake_refund')
11
11
  end
12
12
 
13
13
  def test_refund_should_be_defined
14
14
  refute_nil Razorpay::Refund
15
15
  end
16
16
 
17
+ def test_fetch_all_refunds_for_payment
18
+ stub_get(%r{payments/#{@payment_id}/refunds$}, 'refund_collection_for_payment')
19
+ refunds = Razorpay::Payment.fetch(@payment_id).refunds
20
+ assert_instance_of Razorpay::Collection, refunds
21
+ end
22
+
17
23
  def test_fetch_all_refunds
18
- stub_get(%r{payments/#{@payment_id}/refunds$}, 'refund_collection')
19
- refunds = Razorpay::Payment.fetch(@payment_id).refunds.all
24
+ stub_get(/refunds$/, 'refund_collection')
25
+ refunds = Razorpay::Refund.all
20
26
  assert_instance_of Razorpay::Collection, refunds
21
27
  end
22
28
 
23
29
  def test_fetch_specific_refund
24
- refund_id = 'fake_refund_id'
25
- stub_get(%r{payments/#{@payment_id}/refunds/#{refund_id}$}, 'fake_refund')
26
- refund = Razorpay::Payment.fetch(@payment_id).refunds.fetch('fake_refund_id')
30
+ refund = Razorpay::Refund.fetch(@refund_id)
31
+ assert_instance_of Razorpay::Refund, refund
32
+ assert_equal refund.id, @refund_id
33
+ end
34
+
35
+ def test_create_refund
36
+ stub_post(/refunds$/, 'fake_refund', "payment_id=#{@payment_id}")
37
+ refund = Razorpay::Refund.create(payment_id: @payment_id)
27
38
  assert_instance_of Razorpay::Refund, refund
28
- assert_equal refund.id, refund_id
39
+ assert_equal refund.payment_id, @payment_id
29
40
  end
30
41
  end
31
42
  end
@@ -0,0 +1,35 @@
1
+ require 'test_helper'
2
+
3
+ module Razorpay
4
+ # Tests for Razorpay::Utility
5
+ class RazorpayUtilityTest < Minitest::Test
6
+ def setup
7
+ Razorpay.setup('key_id', 'key_secret')
8
+ end
9
+
10
+ def test_payment_signature_verification
11
+ payment_response = {
12
+ razorpay_order_id: 'fake_order_id',
13
+ razorpay_payment_id: 'fake_payment_id',
14
+ razorpay_signature: 'b2335e3b0801106b84a7faff035df56ecffde06918c9ddd1f0fafbb37a51cc89'
15
+ }
16
+ Razorpay::Utility.verify_payment_signature(payment_response)
17
+
18
+ payment_response[:razorpay_signature] = '_dummy_signature' * 4
19
+ assert_raises(SecurityError) do
20
+ Razorpay::Utility.verify_payment_signature(payment_response)
21
+ end
22
+ end
23
+
24
+ def test_webhook_signature_verification
25
+ webhook_body = fixture_file('fake_payment_authorized_webhook')
26
+ signature = 'd60e67fd884556c045e9be7dad57903e33efc7172c17c6e3ef77db42d2b366e9'
27
+ Razorpay::Utility.verify_webhook_signature(signature, webhook_body)
28
+
29
+ signature = '_dummy_signature' * 4
30
+ assert_raises(SecurityError) do
31
+ Razorpay::Utility.verify_webhook_signature(signature, webhook_body)
32
+ end
33
+ end
34
+ end
35
+ end
data/test/test_helper.rb CHANGED
@@ -1,6 +1,10 @@
1
+ require 'coveralls'
1
2
  require 'simplecov'
2
3
  require 'minitest/autorun'
3
4
  require 'webmock/minitest'
5
+ require 'razorpay'
6
+
7
+ Coveralls.wear! if ENV['CI']
4
8
 
5
9
  def fixture_file(filename)
6
10
  return '' if filename == ''
@@ -27,3 +31,11 @@ def stub_post(*args)
27
31
  url = args[0]
28
32
  stub_request(:post, url).with(body: data).to_return(response)
29
33
  end
34
+
35
+ def stub_put(*args)
36
+ # The last argument is put data
37
+ data = args.pop
38
+ response = stub_response(*args)
39
+ url = args[0]
40
+ stub_request(:put, url).with(body: data).to_return(response)
41
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: razorpay
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abhay Rana
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-22 00:00:00.000000000 Z
11
+ date: 2017-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -16,70 +16,84 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '10.5'
19
+ version: '12.0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '10.5'
26
+ version: '12.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '5.8'
33
+ version: '5.10'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '5.8'
40
+ version: '5.10'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: webmock
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '1.24'
47
+ version: '2.3'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '1.24'
54
+ version: '2.3'
55
55
  - !ruby/object:Gem::Dependency
56
- name: simplecov
56
+ name: coveralls
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0.11'
61
+ version: '0.8'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0.11'
68
+ version: '0.8'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.47'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.47'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: httparty
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: '0.13'
89
+ version: '0.14'
76
90
  type: :runtime
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: '0.13'
96
+ version: '0.14'
83
97
  description: Official ruby bindings for the Razorpay API
84
98
  email:
85
99
  - nemo@razorpay.com
@@ -99,6 +113,7 @@ files:
99
113
  - Rakefile
100
114
  - lib/ca-bundle.crt
101
115
  - lib/razorpay.rb
116
+ - lib/razorpay/card.rb
102
117
  - lib/razorpay/collection.rb
103
118
  - lib/razorpay/constants.rb
104
119
  - lib/razorpay/customer.rb
@@ -113,13 +128,18 @@ files:
113
128
  - lib/razorpay/payment.rb
114
129
  - lib/razorpay/refund.rb
115
130
  - lib/razorpay/request.rb
131
+ - lib/razorpay/utility.rb
116
132
  - razorpay-ruby.gemspec
117
133
  - test/fixtures/bad_request_error.json
134
+ - test/fixtures/customer_collection.json
118
135
  - test/fixtures/fake_captured_payment.json
136
+ - test/fixtures/fake_card.json
119
137
  - test/fixtures/fake_customer.json
138
+ - test/fixtures/fake_customer_edited.json
120
139
  - test/fixtures/fake_invoice.json
121
140
  - test/fixtures/fake_order.json
122
141
  - test/fixtures/fake_payment.json
142
+ - test/fixtures/fake_payment_authorized_webhook.json
123
143
  - test/fixtures/fake_refund.json
124
144
  - test/fixtures/hello_response.json
125
145
  - test/fixtures/invoice_collection.json
@@ -128,6 +148,8 @@ files:
128
148
  - test/fixtures/payment_collection.json
129
149
  - test/fixtures/payment_collection_with_one_payment.json
130
150
  - test/fixtures/refund_collection.json
151
+ - test/fixtures/refund_collection_for_payment.json
152
+ - test/razorpay/test_card.rb
131
153
  - test/razorpay/test_customer.rb
132
154
  - test/razorpay/test_entity.rb
133
155
  - test/razorpay/test_errors.rb
@@ -136,6 +158,7 @@ files:
136
158
  - test/razorpay/test_payment.rb
137
159
  - test/razorpay/test_razorpay.rb
138
160
  - test/razorpay/test_refund.rb
161
+ - test/razorpay/test_utility.rb
139
162
  - test/test_helper.rb
140
163
  homepage: https://razorpay.com/
141
164
  licenses:
@@ -163,11 +186,15 @@ specification_version: 4
163
186
  summary: Razorpay's Ruby API
164
187
  test_files:
165
188
  - test/fixtures/bad_request_error.json
189
+ - test/fixtures/customer_collection.json
166
190
  - test/fixtures/fake_captured_payment.json
191
+ - test/fixtures/fake_card.json
167
192
  - test/fixtures/fake_customer.json
193
+ - test/fixtures/fake_customer_edited.json
168
194
  - test/fixtures/fake_invoice.json
169
195
  - test/fixtures/fake_order.json
170
196
  - test/fixtures/fake_payment.json
197
+ - test/fixtures/fake_payment_authorized_webhook.json
171
198
  - test/fixtures/fake_refund.json
172
199
  - test/fixtures/hello_response.json
173
200
  - test/fixtures/invoice_collection.json
@@ -176,6 +203,8 @@ test_files:
176
203
  - test/fixtures/payment_collection.json
177
204
  - test/fixtures/payment_collection_with_one_payment.json
178
205
  - test/fixtures/refund_collection.json
206
+ - test/fixtures/refund_collection_for_payment.json
207
+ - test/razorpay/test_card.rb
179
208
  - test/razorpay/test_customer.rb
180
209
  - test/razorpay/test_entity.rb
181
210
  - test/razorpay/test_errors.rb
@@ -184,4 +213,5 @@ test_files:
184
213
  - test/razorpay/test_payment.rb
185
214
  - test/razorpay/test_razorpay.rb
186
215
  - test/razorpay/test_refund.rb
216
+ - test/razorpay/test_utility.rb
187
217
  - test/test_helper.rb