razorpay 3.2.1 → 3.2.3

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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -0
  3. data/README.md +18 -1
  4. data/documents/customer.md +242 -0
  5. data/documents/dispute.md +301 -0
  6. data/documents/documents.md +65 -0
  7. data/documents/oauth_token.md +142 -0
  8. data/documents/order.md +71 -0
  9. data/documents/payment.md +253 -0
  10. data/documents/transfers.md +40 -0
  11. data/lib/razorpay/constants.rb +6 -1
  12. data/lib/razorpay/customer.rb +16 -0
  13. data/lib/razorpay/dispute.rb +26 -0
  14. data/lib/razorpay/document.rb +19 -0
  15. data/lib/razorpay/oauth_token.rb +109 -0
  16. data/lib/razorpay/order.rb +8 -0
  17. data/lib/razorpay/payload_validator.rb +93 -0
  18. data/lib/razorpay/payment.rb +4 -0
  19. data/lib/razorpay/request.rb +24 -7
  20. data/lib/razorpay/transfer.rb +4 -0
  21. data/lib/razorpay/utility.rb +24 -0
  22. data/lib/razorpay/validation_config.rb +11 -0
  23. data/lib/razorpay.rb +10 -1
  24. data/test/fixtures/dispute_collection.json +67 -0
  25. data/test/fixtures/dispute_error.json +10 -0
  26. data/test/fixtures/document_error.json +10 -0
  27. data/test/fixtures/error_customer.json +10 -0
  28. data/test/fixtures/error_eligibility.json +10 -0
  29. data/test/fixtures/error_eligibility_check.json +10 -0
  30. data/test/fixtures/fake_bank_account.json +9 -0
  31. data/test/fixtures/fake_dispute.json +29 -0
  32. data/test/fixtures/fake_document.json +9 -0
  33. data/test/fixtures/fake_eligiblity.json +79 -0
  34. data/test/fixtures/fake_fulfillment.json +10 -0
  35. data/test/fixtures/fake_oauth_token.json +8 -0
  36. data/test/fixtures/fake_payment_expanded_details.json +38 -0
  37. data/test/fixtures/fake_payment_expanded_details_card.json +50 -0
  38. data/test/fixtures/fake_revoke_token.json +3 -0
  39. data/test/fixtures/fake_rto.json +15 -0
  40. data/test/fixtures/order_error.json +10 -0
  41. data/test/fixtures/payment_error.json +10 -0
  42. data/test/fixtures/reversals_collection.json +22 -0
  43. data/test/fixtures/transfer_error.json +10 -0
  44. data/test/razorpay/test_customer.rb +105 -0
  45. data/test/razorpay/test_dispute.rb +98 -0
  46. data/test/razorpay/test_document.rb +27 -0
  47. data/test/razorpay/test_oauth_token.rb +105 -0
  48. data/test/razorpay/test_order.rb +43 -1
  49. data/test/razorpay/test_payload_validator.rb +61 -0
  50. data/test/razorpay/test_payment.rb +23 -1
  51. data/test/razorpay/test_razorpay.rb +17 -0
  52. data/test/razorpay/test_transfer.rb +17 -0
  53. data/test/razorpay/test_utility.rb +34 -0
  54. metadata +59 -3
@@ -0,0 +1,109 @@
1
+ require 'razorpay/request'
2
+ require 'razorpay/entity'
3
+ require 'razorpay/payload_validator'
4
+ require 'razorpay/validation_config'
5
+
6
+ module Razorpay
7
+ # OAuth APIs allow to you create and manage access tokens
8
+ class OAuthToken < Entity
9
+ def self.request
10
+ Razorpay::Request.new('token', Razorpay::AUTH_HOST)
11
+ end
12
+
13
+ def self.get_auth_url(options)
14
+ validate_auth_url_request(options)
15
+ uri = URI.join(Razorpay::AUTH_URL, '/authorize')
16
+
17
+ query_params = {
18
+ 'response_type' => 'code',
19
+ 'client_id' => options['client_id'],
20
+ 'redirect_uri' => options['redirect_uri'],
21
+ 'state' => options['state']
22
+ }
23
+
24
+ options['scopes'].each { |scope| query_params["scope[]"] = scope }
25
+
26
+ if options.has_key?('onboarding_signature')
27
+ query_params['onboarding_signature'] = options['onboarding_signature']
28
+ end
29
+ uri.query = URI.encode_www_form(query_params)
30
+ uri.to_s
31
+ end
32
+
33
+ def self.get_access_token(options)
34
+ validate_access_token_request(options)
35
+ r = request
36
+ r.request :post, "/token", options
37
+ end
38
+
39
+ def self.refresh_token(options)
40
+ options['grant_type'] = 'refresh_token'
41
+ validate_refresh_token_request(options)
42
+ r = request
43
+ r.request :post, "/token", options
44
+ end
45
+
46
+ def self.revoke_token(options)
47
+ validate_revoke_token_request(options)
48
+ r = request
49
+ r.request :post, "/revoke", options
50
+ end
51
+
52
+ class << self
53
+
54
+ private
55
+
56
+ def validate_auth_url_request(options)
57
+ Razorpay::PayloadValidator.validate(options, get_validations_for_auth_request_url)
58
+ end
59
+
60
+ def validate_access_token_request(options)
61
+ Razorpay::PayloadValidator.validate(options, get_validations_for_access_token_request)
62
+ end
63
+
64
+ def validate_refresh_token_request(options)
65
+ Razorpay::PayloadValidator.validate(options, get_validations_for_refresh_token_request)
66
+ end
67
+
68
+ def validate_revoke_token_request(options)
69
+ Razorpay::PayloadValidator.validate(options, get_validations_for_revoke_token_request)
70
+ end
71
+
72
+ def get_validations_for_auth_request_url
73
+ [
74
+ Razorpay::ValidationConfig.new('client_id', [:id]),
75
+ Razorpay::ValidationConfig.new('redirect_uri', [:non_empty_string, :url]),
76
+ Razorpay::ValidationConfig.new('scopes', [:non_null]),
77
+ Razorpay::ValidationConfig.new('state', [:non_empty_string])
78
+ ]
79
+ end
80
+
81
+ def get_validations_for_access_token_request
82
+ [
83
+ Razorpay::ValidationConfig.new('client_id', [:id]),
84
+ Razorpay::ValidationConfig.new('client_secret', [:non_empty_string]),
85
+ Razorpay::ValidationConfig.new('redirect_uri', [:non_empty_string, :url]),
86
+ Razorpay::ValidationConfig.new('grant_type', [:token_grant])
87
+ ]
88
+ end
89
+
90
+ def get_validations_for_refresh_token_request
91
+ [
92
+ Razorpay::ValidationConfig.new('client_id', [:id]),
93
+ Razorpay::ValidationConfig.new('client_secret', [:non_empty_string]),
94
+ Razorpay::ValidationConfig.new('refresh_token', [:non_empty_string]),
95
+ Razorpay::ValidationConfig.new('grant_type', [:token_grant])
96
+ ]
97
+ end
98
+
99
+ def get_validations_for_revoke_token_request
100
+ [
101
+ Razorpay::ValidationConfig.new('client_id', [:id]),
102
+ Razorpay::ValidationConfig.new('client_secret', [:non_empty_string]),
103
+ Razorpay::ValidationConfig.new('token', [:non_empty_string]),
104
+ Razorpay::ValidationConfig.new('token_type_hint', [:non_empty_string])
105
+ ]
106
+ end
107
+ end
108
+ end
109
+ end
@@ -35,5 +35,13 @@ module Razorpay
35
35
  # Docs: https://razorpay.com/docs/api/payments/route/#fetch-transfer-for-an-order
36
36
  request.get "#{id}/?expand[]=transfers&status"
37
37
  end
38
+
39
+ def self.view_rto(id)
40
+ request.post "#{id}/rto_review"
41
+ end
42
+
43
+ def self.edit_fulfillment(id, options = {})
44
+ request.post "#{id}/fulfillment", options
45
+ end
38
46
  end
39
47
  end
@@ -0,0 +1,93 @@
1
+ module Razorpay
2
+
3
+ ValidationType = {
4
+ non_null: :non_null,
5
+ non_empty_string: :non_empty_string,
6
+ url: :url,
7
+ id: :id,
8
+ mode: :mode,
9
+ token_grant: :token_grant
10
+ }
11
+
12
+ # PayloadValidator allows to perform basic validations
13
+ class PayloadValidator
14
+ def self.validate(request, validation_configs)
15
+ validation_configs.each do |config|
16
+ field_name = config.field_name
17
+ config.validations.each do |validation_type|
18
+ apply_validation(request, field_name, validation_type)
19
+ end
20
+ end
21
+ end
22
+
23
+ class << self
24
+
25
+ private
26
+
27
+ def apply_validation(payload, field, validation_type)
28
+ case validation_type
29
+ when ValidationType[:non_null]
30
+ validate_non_null(payload, field)
31
+ when ValidationType[:non_empty_string]
32
+ validate_non_empty_string(payload, field)
33
+ when ValidationType[:url]
34
+ validate_url(payload, field)
35
+ when ValidationType[:id]
36
+ validate_id(payload, field)
37
+ when ValidationType[:mode]
38
+ validate_mode(payload, field)
39
+ when ValidationType[:token_grant]
40
+ validate_grant_type(payload, field)
41
+ end
42
+ end
43
+
44
+ def validate_non_null(payload, field)
45
+ raise Razorpay::Error.new, "Field #{field} cannot be null" unless payload.key?(field) && !payload[field].nil?
46
+ end
47
+
48
+ def validate_non_empty_string(payload, field)
49
+ raise Razorpay::Error.new, "Field #{field} cannot be empty" if payload[field].to_s.strip.empty?
50
+ end
51
+
52
+ def validate_url(payload, field)
53
+ url = payload[field]
54
+ url_regex = /^(http[s]?):\/\/[^\s\/$.?#].[^\s]*$/
55
+
56
+ unless url_regex.match?(url)
57
+ error_message = "Field #{field} is not a valid URL"
58
+ raise Razorpay::Error.new, error_message
59
+ end
60
+ end
61
+
62
+ def validate_id(payload, field)
63
+ validate_non_null(payload, field)
64
+ validate_non_empty_string(payload, field)
65
+ value = payload[field]
66
+ id_regex = /^[A-Za-z0-9]{1,14}$/
67
+
68
+ unless value.match?(id_regex)
69
+ error_message = "Field #{field} is not a valid ID"
70
+ raise Razorpay::Error.new, error_message
71
+ end
72
+ end
73
+
74
+ def validate_mode(payload, field)
75
+ validate_non_null(payload, field)
76
+ unless ["test", "live"].include?(payload[field])
77
+ error_message = "Invalid value provided for field #{field}"
78
+ raise Razorpay::Error.new, error_message
79
+ end
80
+ end
81
+
82
+ def validate_grant_type(payload, field)
83
+ validate_non_null(payload, field)
84
+ case payload[field]
85
+ when 'authorization_code'
86
+ validate_non_null(payload, 'code');
87
+ when 'refresh_token'
88
+ validate_non_null(payload, 'refresh_token');
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -112,5 +112,9 @@ module Razorpay
112
112
  def self.validate_vpa(data={})
113
113
  request.post "validate/vpa" , data
114
114
  end
115
+
116
+ def self.expand_details(id, options={})
117
+ request.get "#{id}", options
118
+ end
115
119
  end
116
120
  end
@@ -11,20 +11,30 @@ module Razorpay
11
11
 
12
12
  ssl_ca_file File.dirname(__FILE__) + '/../ca-bundle.crt'
13
13
 
14
- def initialize(entity_name = nil)
15
- self.class.base_uri(Razorpay::BASE_URI)
14
+ def initialize(entity_name = nil, host = Razorpay::API_HOST)
15
+ self.class.base_uri(get_base_url(host))
16
16
  @entity_name = entity_name
17
17
  custom_headers = Razorpay.custom_headers || {}
18
18
  predefined_headers = {
19
19
  'User-Agent' => "Razorpay-Ruby/#{Razorpay::VERSION}; Ruby/#{RUBY_VERSION}"
20
20
  }
21
+
21
22
  # Order is important to give precedence to predefined headers
22
23
  headers = custom_headers.merge(predefined_headers)
23
- @options = {
24
- basic_auth: Razorpay.auth,
25
- timeout: 30,
26
- headers: headers
27
- }
24
+
25
+ if Razorpay.auth_type == Razorpay::OAUTH
26
+ @options = {
27
+ timeout: 30,
28
+ headers: headers
29
+ }
30
+ headers['Authorization'] = 'Bearer ' + Razorpay.access_token
31
+ else
32
+ @options = {
33
+ basic_auth: Razorpay.auth,
34
+ timeout: 30,
35
+ headers: headers
36
+ }
37
+ end
28
38
  end
29
39
 
30
40
  def fetch(id, version="v1")
@@ -74,6 +84,13 @@ module Razorpay
74
84
  self.class.send(method, url, @options)
75
85
  end
76
86
 
87
+ def get_base_url(host)
88
+ if host == Razorpay::AUTH_HOST
89
+ return Razorpay::AUTH_URL
90
+ end
91
+ Razorpay::BASE_URI
92
+ end
93
+
77
94
  # Since we need to change the base route
78
95
  def make_test_request
79
96
  self.class.get Razorpay::TEST_URL, @options
@@ -31,5 +31,9 @@ module Razorpay
31
31
  def self.fetch_settlements
32
32
  request.get "?expand[]=recipient_settlement"
33
33
  end
34
+
35
+ def self.reversals(id)
36
+ request.get "#{id}/reversals"
37
+ end
34
38
  end
35
39
  end
@@ -26,6 +26,11 @@ module Razorpay
26
26
  verify_signature(body, signature, secret)
27
27
  end
28
28
 
29
+ def self.generate_onboarding_signature(body, secret)
30
+ json_data = body.to_json
31
+ encrypt(json_data, secret);
32
+ end
33
+
29
34
  class << self
30
35
  private
31
36
 
@@ -52,6 +57,25 @@ module Razorpay
52
57
 
53
58
  r.zero?
54
59
  end
60
+
61
+ def encrypt(data, secret)
62
+ iv = secret[0, 12]
63
+ key = secret[0, 16]
64
+
65
+ cipher = OpenSSL::Cipher.new('aes-128-gcm')
66
+ cipher.encrypt
67
+ cipher.key = key
68
+ cipher.iv = iv
69
+
70
+ cipher.auth_data = ""
71
+
72
+ encrypted = cipher.update(data) + cipher.final
73
+
74
+ tag = cipher.auth_tag
75
+ combined_encrypted_data = encrypted + tag
76
+
77
+ encrypted_data_hex = combined_encrypted_data.unpack1("H*")
78
+ end
55
79
  end
56
80
  end
57
81
  end
@@ -0,0 +1,11 @@
1
+ module Razorpay
2
+
3
+ class ValidationConfig
4
+ attr_reader :field_name, :validations
5
+
6
+ def initialize(field_name, validations)
7
+ @field_name = field_name
8
+ @validations = validations
9
+ end
10
+ end
11
+ end
data/lib/razorpay.rb CHANGED
@@ -26,15 +26,24 @@ require 'razorpay/token'
26
26
  require 'razorpay/product'
27
27
  require 'razorpay/stakeholder'
28
28
  require 'razorpay/account'
29
+ require 'razorpay/document'
30
+ require 'razorpay/dispute'
31
+ require 'razorpay/oauth_token'
29
32
 
30
33
  # Base Razorpay module
31
34
  module Razorpay
32
35
  class << self
33
- attr_accessor :auth, :custom_headers
36
+ attr_accessor :auth, :custom_headers, :access_token, :auth_type
34
37
  end
35
38
 
36
39
  def self.setup(key_id, key_secret)
37
40
  self.auth = { username: key_id, password: key_secret }
41
+ self.auth_type = Razorpay::PRIVATE_AUTH
42
+ end
43
+
44
+ def self.setup_with_oauth(access_token)
45
+ self.access_token = access_token
46
+ self.auth_type = Razorpay::OAUTH
38
47
  end
39
48
 
40
49
  def self.headers=(headers = {})
@@ -0,0 +1,67 @@
1
+ {
2
+ "entity": "collection",
3
+ "count": 2,
4
+ "items": [
5
+ {
6
+ "id": "disp_Esz7KAitoYM7PJ",
7
+ "entity": "dispute",
8
+ "payment_id": "pay_EsyWjHrfzb59eR",
9
+ "amount": 10000,
10
+ "currency": "INR",
11
+ "amount_deducted": 0,
12
+ "reason_code": "pre_arbitration",
13
+ "respond_by": 1590604200,
14
+ "status": "open",
15
+ "phase": "pre_arbitration",
16
+ "created_at": 1590059211,
17
+ "evidence": {
18
+ "amount": 10000,
19
+ "summary": null,
20
+ "shipping_proof": null,
21
+ "billing_proof": null,
22
+ "cancellation_proof": null,
23
+ "customer_communication": null,
24
+ "proof_of_service": null,
25
+ "explanation_letter": null,
26
+ "refund_confirmation": null,
27
+ "access_activity_log": null,
28
+ "refund_cancellation_policy": null,
29
+ "term_and_conditions": null,
30
+ "others": null,
31
+ "submitted_at": null
32
+ }
33
+ },
34
+ {
35
+ "id": "disp_Esyvk3kZj0isXk",
36
+ "entity": "dispute",
37
+ "payment_id": "pay_EsyWjHrfzb59eR",
38
+ "amount": 5000,
39
+ "currency": "INR",
40
+ "amount_deducted": 0,
41
+ "reason_code": "warning_bulletin_or_exception_file",
42
+ "respond_by": 1590604200,
43
+ "status": "won",
44
+ "phase": "chargeback",
45
+ "created_at": 1590058554,
46
+ "evidence": {
47
+ "amount": 5000,
48
+ "summary": null,
49
+ "shipping_proof": [
50
+ "doc_EFtmUsbwpXwBH9",
51
+ "doc_EFtmUsbwpXwBH8"
52
+ ],
53
+ "billing_proof": null,
54
+ "cancellation_proof": null,
55
+ "customer_communication": null,
56
+ "proof_of_service": null,
57
+ "explanation_letter": null,
58
+ "refund_confirmation": null,
59
+ "access_activity_log": null,
60
+ "refund_cancellation_policy": null,
61
+ "term_and_conditions": null,
62
+ "others": null,
63
+ "submitted_at": 1590604100
64
+ }
65
+ }
66
+ ]
67
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "error": {
3
+ "code": "BAD_REQUEST_ERROR",
4
+ "description": "The id provided does not exist",
5
+ "source": "business",
6
+ "step": "payment_initiation",
7
+ "reason": "input_validation_failed",
8
+ "metadata": {}
9
+ }
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "error": {
3
+ "code": "BAD_REQUEST_ERROR",
4
+ "description": "Invalid file id provided or merchant is unauthorized to access the fileId(s) provided",
5
+ "source": "NA",
6
+ "step": "NA",
7
+ "reason": "NA",
8
+ "metadata": {}
9
+ }
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "error": {
3
+ "code": "BAD_REQUEST_ERROR",
4
+ "description": "The id provided does not exist",
5
+ "source": "business",
6
+ "step": "payment_initiation",
7
+ "reason": "input_validation_failed",
8
+ "metadata": {}
9
+ }
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "error": {
3
+ "code": "BAD_REQUEST_ERROR",
4
+ "description": "The eligibility id does not exist.",
5
+ "source": "NA",
6
+ "step": "NA",
7
+ "reason": "NA",
8
+ "metadata": {}
9
+ }
10
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "error": {
3
+ "code": "BAD_REQUEST_ERROR",
4
+ "description": "Amount is required.",
5
+ "source": "NA",
6
+ "step": "NA",
7
+ "reason": "NA",
8
+ "metadata": {}
9
+ }
10
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "id": "ba_LSZht1Cm7xFTwF",
3
+ "entity": "bank_account",
4
+ "ifsc": "ICIC0001207",
5
+ "bank_name": "ICICI Bank",
6
+ "name": "Gaurav Kumar",
7
+ "notes": [],
8
+ "account_number": "XXXXXXXXXXXXXXX0434"
9
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "id": "disp_XXXXXXXXXXXXX",
3
+ "entity": "dispute",
4
+ "payment_id": "pay_EsyWjHrfzb59eR",
5
+ "amount": 10000,
6
+ "currency": "INR",
7
+ "amount_deducted": 0,
8
+ "reason_code": "pre_arbitration",
9
+ "respond_by": 1590604200,
10
+ "status": "open",
11
+ "phase": "pre_arbitration",
12
+ "created_at": 1590059211,
13
+ "evidence": {
14
+ "amount": 10000,
15
+ "summary": "goods delivered",
16
+ "shipping_proof": null,
17
+ "billing_proof": null,
18
+ "cancellation_proof": null,
19
+ "customer_communication": null,
20
+ "proof_of_service": null,
21
+ "explanation_letter": null,
22
+ "refund_confirmation": null,
23
+ "access_activity_log": null,
24
+ "refund_cancellation_policy": null,
25
+ "term_and_conditions": null,
26
+ "others": null,
27
+ "submitted_at": null
28
+ }
29
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "entity": "document",
3
+ "id": "doc_O4KANwWi2kHGiV",
4
+ "purpose": "dispute_evidence",
5
+ "created_at": 1714368859,
6
+ "mime_type": "image/jpeg",
7
+ "display_name": "Screenshot 2022-09-12 at 5.48.23 PM",
8
+ "size": 334201
9
+ }
@@ -0,0 +1,79 @@
1
+ {
2
+ "amount": "500000",
3
+ "customer": {
4
+ "id": "KkBhM9EC1Y0HTm",
5
+ "contact": "+918220722114"
6
+ },
7
+ "instruments": [
8
+ {
9
+ "method": "emi",
10
+ "issuer": "HDFC",
11
+ "type": "debit",
12
+ "eligibility_req_id": "elig_KkCNLzlNeMYQyZ",
13
+ "eligibility": {
14
+ "status": "eligible"
15
+ }
16
+ },
17
+ {
18
+ "method": "paylater",
19
+ "provider": "getsimpl",
20
+ "eligibility_req_id": "elig_KkCNLzlNeMYQyZ",
21
+ "eligibility": {
22
+ "status": "eligible"
23
+ }
24
+ },
25
+ {
26
+ "method": "paylater",
27
+ "provider": "icic",
28
+ "eligibility_req_id": "elig_KkCNLzlNeMYQyZ",
29
+ "eligibility": {
30
+ "status": "eligible"
31
+ }
32
+ },
33
+ {
34
+ "method": "cardless_emi",
35
+ "provider": "walnut369",
36
+ "eligibility_req_id": "elig_KkCNLzlNeMYQyZ",
37
+ "eligibility": {
38
+ "status": "ineligible",
39
+ "error": {
40
+ "code": "GATEWAY_ERROR",
41
+ "description": "The customer has not been approved by the partner.",
42
+ "source": "business",
43
+ "step": "inquiry",
44
+ "reason": "user_not_approved"
45
+ }
46
+ }
47
+ },
48
+ {
49
+ "method": "cardless_emi",
50
+ "provider": "zestmoney",
51
+ "eligibility_req_id": "elig_KkCNLzlNeMYQyZ",
52
+ "eligibility": {
53
+ "status": "ineligible",
54
+ "error": {
55
+ "code": "GATEWAY_ERROR",
56
+ "description": "The customer has exhausted their credit limit.",
57
+ "source": "business",
58
+ "step": "inquiry",
59
+ "reason": "credit_limit_exhausted"
60
+ }
61
+ }
62
+ },
63
+ {
64
+ "method": "paylater",
65
+ "provider": "lazypay",
66
+ "eligibility_req_id": "elig_KkCNLzlNeMYQyZ",
67
+ "eligibility": {
68
+ "status": "ineligible",
69
+ "error": {
70
+ "code": "GATEWAY_ERROR",
71
+ "description": "The order amount is less than the minimum transaction amount.",
72
+ "source": "business",
73
+ "step": "inquiry",
74
+ "reason": "min_amt_required"
75
+ }
76
+ }
77
+ }
78
+ ]
79
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "entity": "order.fulfillment",
3
+ "order_id": "EKwxwAgItXXXX",
4
+ "payment_method": "upi",
5
+ "shipping": {
6
+ "waybill": "123456789",
7
+ "status": "rto",
8
+ "provider": "Bluedart"
9
+ }
10
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "public_token": "rzp_test_oauth_9xu1rkZqoXlClS",
3
+ "token_type": "Bearer",
4
+ "expires_in": 7862400,
5
+ "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IkY1Z0NQYkhhRzRjcUpnIn0.eyJhdWQiOiJGNFNNeEgxanMxbkpPZiIsImp0aSI6IkY1Z0NQYkhhRzRjcUpnIiwiaWF0IjoxNTkyODMxMDExLCJuYmYiOjE1OTI4MzEwMTEsInN1YiI6IiIsImV4cCI6MTYwMDc3OTgxMSwidXNlcl9pZCI6IkYycVBpejJEdzRPRVFwIiwibWVyY2hhbnRfaWQiOiJGMnFQaVZ3N0lNV01GSyIsInNjb3BlcyI6WyJyZWFkX29ubHkiXX0.Wwqt5czhoWpVzP5_aoiymKXoGj-ydo-4A_X2jf_7rrSvk4pXdqzbA5BMrHxPdPbeFQWV6vsnsgbf99Q3g-W4kalHyH67LfAzc3qnJ-mkYDkFY93tkeG-MCco6GJW-Jm8xhaV9EPUak7z9J9jcdluu9rNXYMtd5qxD8auyRYhEgs",
6
+ "refresh_token": "def50200f42e07aded65a323f6c53181d802cc797b62cc5e78dd8038d6dff253e5877da9ad32f463a4da0ad895e3de298cbce40e162202170e763754122a6cb97910a1f58e2378ee3492dc295e1525009cccc45635308cce8575bdf373606c453ebb5eb2bec062ca197ac23810cf9d6cf31fbb9fcf5b7d4de9bf524c89a4aa90599b0151c9e4e2fa08acb6d2fe17f30a6cfecdfd671f090787e821f844e5d36f5eacb7dfb33d91e83b18216ad0ebeba2bef7721e10d436c3984daafd8654ed881c581d6be0bdc9ebfaee0dc5f9374d7184d60aae5aa85385690220690e21bc93209fb8a8cc25a6abf1108d8277f7c3d38217b47744d7",
7
+ "razorpay_account_id": "acc_Dhk2qDbmu6FwZH"
8
+ }