payjp 0.0.6 → 0.0.14

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ebc7ca3b834edcac9e21591f4276ab0565f2737b
4
- data.tar.gz: a33c549105cf8879e36f2138b2c25c354e470960
2
+ SHA256:
3
+ metadata.gz: 32fcd8c9e2569e568458d8eac4dc882d1900e75577f8ff686801085b7d202385
4
+ data.tar.gz: a4dd505473e1bf7fbd0fcd56c1620f00d5f4a39781f1c1ffdabc623f55d16464
5
5
  SHA512:
6
- metadata.gz: 3eee26dfe4f02da8e58681cfa911e0366684d2331ef277ce42ef9f1b639026799b1a155897c6612301e106d0ace91757350ff123060e57fb799fb6a4fbf46d43
7
- data.tar.gz: baa39ffbea0e3be47a2dfcc6b671461ecfef2f57f299fa09ac78f126cfd5ee98b4f963ae4562255616c810753a4ece35e7302aeaf33a440259d6b7a1ad31ef10
6
+ metadata.gz: 686404e37c62aafe0ce82a76264db1003651b3f43cc027cdae712911db20aaa3f0876ed7de74737d827e37fd97123406837dcaa4b6478c257f17ec7d411a1c0e
7
+ data.tar.gz: 257f55f34bd2aa2347c14cbf0dadaa49229a36c21a6d130751f24984d175a01f4d31e1ef5418cff772c883c8bcfc0c47c584995ed03bcde7a7a8e0107d2a340f
@@ -0,0 +1,24 @@
1
+ name: Publish Ruby Package
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ deploy:
9
+
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - uses: actions/checkout@v3
14
+ - name: Set up Ruby
15
+ uses: ruby/setup-ruby@v1
16
+ with:
17
+ ruby-version: '2.7'
18
+ bundler-cache: true
19
+ - name: Build and publish
20
+ env:
21
+ GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
22
+ run: |
23
+ bundle exec rake build
24
+ bundle exec gem push pkg/payjp-*.gem
@@ -0,0 +1,20 @@
1
+ name: Ruby Build Test
2
+
3
+ on: push
4
+
5
+ jobs:
6
+ build-test:
7
+
8
+ runs-on: ubuntu-20.04
9
+ strategy:
10
+ matrix:
11
+ ruby-version: [2.0.0, 2.1, 2.2, 2.3.0, 2.7.0, jruby-9.2.17.0]
12
+ steps:
13
+ - uses: actions/checkout@v3
14
+ - name: Set up Ruby ${{ matrix.ruby-version }}
15
+ uses: ruby/setup-ruby@v1
16
+ with:
17
+ ruby-version: ${{ matrix.ruby-version }}
18
+ bundler-cache: true
19
+ - name: Run tests
20
+ run: bundle exec rake
data/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # PAY.JP for Ruby
2
+
3
+ ## How to Use
4
+
5
+ ```ruby
6
+ require 'payjp'
7
+ Payjp.api_key = 'sk_test_c62fade9d045b54cd76d7036'
8
+ Payjp.open_timeout = 30 # optionally
9
+ Payjp.read_timeout = 90 # optionally
10
+
11
+ # ex, create charge
12
+ charge = Payjp::Charge.create(
13
+ :amount => 3500,
14
+ :card => 'token_id',
15
+ :currency => 'jpy',
16
+ )
17
+ ```
18
+
19
+ | `Payjp` variables | type | required | description |
20
+ | ----------------- | ---- | -------- | ----------- |
21
+ | api_key | String | yes | your secret key |
22
+ | open_timeout | Integer | no | the second to wait for TCP connection opening (default 30) |
23
+ | read_timeout | Integer | no | the second to wait from request to reading response (default 90) |
24
+
25
+ For detail, See [PAY.JP API Docs](https://pay.jp/docs/api/)
26
+
27
+ ## Installation
28
+
29
+ ```sh
30
+ gem install payjp
31
+ ```
32
+
33
+ If you want to build the gem from source:
34
+
35
+ ```sh
36
+ gem build payjp.gemspec
37
+ ```
38
+
39
+ ### Requirements
40
+
41
+ * Ruby 2.0.0 or above.
42
+ * rest-client
43
+
44
+ ### Retry on HTTP Status Code 429
45
+ * See [Rate Limit Guideline](https://pay.jp/docs/guideline-rate-limit#2-%E3%83%AA%E3%83%88%E3%83%A9%E3%82%A4)
46
+ * When you exceeded rate-limit, you can retry request by setting `max_retry`
47
+ like `Payjp.max_retry = 3` .
48
+ * The retry interval base value is `retry_initial_delay`
49
+ Adjust the value like `Payjp.retry_initial_delay = 4`
50
+ The smaller is shorter.
51
+ * The Maximum retry time is `retry_max_delay`.
52
+ Adjust the value like 'Payjp.retry_max_delay = 32'
53
+ * The retry interval calcurating is based on "Exponential backoff with equal jitter" algorithm.
54
+ See https://aws.amazon.com/jp/blogs/architecture/exponential-backoff-and-jitter/
55
+
56
+ how to use
57
+
58
+ ```ruby
59
+ require 'payjp'
60
+ Payjp.api_key = 'sk_test_c62fade9d045b54cd76d7036'
61
+ Payjp.max_retry = 3
62
+ Payjp.retry_initial_delay = 2
63
+ Payjp.retry_max_delay = 32
64
+
65
+ charge = Payjp::Charge.create(
66
+ :amount => 3500,
67
+ :card => 'token_id',
68
+ :currency => 'jpy',
69
+ )
70
+ ```
71
+
72
+ ### Bundler
73
+
74
+ If you are installing via bundler, you should be sure to use the https
75
+ rubygems source in your Gemfile, as any gems fetched over http could potentially be
76
+ compromised in transit and alter the code of gems fetched securely over https:
77
+
78
+ ```
79
+ source 'https://rubygems.org'
80
+
81
+ gem 'rails'
82
+ gem 'payjp'
83
+ ```
84
+
85
+ ## Development
86
+
87
+ Test cases can be run with: `bundle exec rake test`
@@ -0,0 +1,5 @@
1
+ module Payjp
2
+ class Balance < APIResource
3
+ include Payjp::APIOperations::List
4
+ end
5
+ end
data/lib/payjp/charge.rb CHANGED
@@ -19,6 +19,11 @@ module Payjp
19
19
  refresh_from(response, opts)
20
20
  end
21
21
 
22
+ def tds_finish(params = {}, opts = {})
23
+ response, opts = request(:post, tds_finish_url, params, opts)
24
+ refresh_from(response, opts)
25
+ end
26
+
22
27
  private
23
28
 
24
29
  def refund_url
@@ -32,5 +37,9 @@ module Payjp
32
37
  def reauth_url
33
38
  url + '/reauth'
34
39
  end
40
+
41
+ def tds_finish_url
42
+ url + '/tds_finish'
43
+ end
35
44
  end
36
45
  end
@@ -0,0 +1,16 @@
1
+ module Payjp
2
+ class Statement < APIResource
3
+ include Payjp::APIOperations::List
4
+
5
+ def statement_urls(params = {}, opts = {})
6
+ response, opts = request(:post, statement_urls_url, params, opts)
7
+ response
8
+ end
9
+
10
+ private
11
+
12
+ def statement_urls_url
13
+ url + '/statement_urls'
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ module Payjp
2
+ class Tenant < APIResource
3
+ include Payjp::APIOperations::Create
4
+ include Payjp::APIOperations::Delete
5
+ include Payjp::APIOperations::Update
6
+ include Payjp::APIOperations::List
7
+
8
+ def create_application_urls(params = {}, opts = {})
9
+ response, opts = request(:post, create_application_urls_url, params, opts)
10
+ response
11
+ end
12
+
13
+ private
14
+
15
+ def create_application_urls_url
16
+ url + '/application_urls'
17
+ end
18
+ end
19
+ end
data/lib/payjp/term.rb ADDED
@@ -0,0 +1,5 @@
1
+ module Payjp
2
+ class Term < APIResource
3
+ include Payjp::APIOperations::List
4
+ end
5
+ end
data/lib/payjp/util.rb CHANGED
@@ -22,12 +22,16 @@ module Payjp
22
22
 
23
23
  # business objects
24
24
  'account' => Account,
25
+ 'balance' => Balance,
25
26
  'card' => Card,
26
27
  'charge' => Charge,
27
28
  'customer' => Customer,
29
+ 'tenant' => Tenant,
28
30
  'event' => Event,
29
31
  'plan' => Plan,
32
+ 'statement' => Statement,
30
33
  'subscription' => Subscription,
34
+ 'term' => Term,
31
35
  'token' => Token,
32
36
  'transfer' => Transfer
33
37
  }
data/lib/payjp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Payjp
2
- VERSION = '0.0.6'
2
+ VERSION = '0.0.14'
3
3
  end
data/lib/payjp.rb CHANGED
@@ -33,7 +33,11 @@ require 'payjp/token'
33
33
  require 'payjp/event'
34
34
  require 'payjp/transfer'
35
35
  require 'payjp/card'
36
+ require 'payjp/statement'
36
37
  require 'payjp/subscription'
38
+ require 'payjp/tenant'
39
+ require 'payjp/term'
40
+ require 'payjp/balance'
37
41
 
38
42
  # Errors
39
43
  require 'payjp/errors/payjp_error'
@@ -46,27 +50,43 @@ require 'payjp/errors/authentication_error'
46
50
  module Payjp
47
51
  @api_base = 'https://api.pay.jp'
48
52
  @open_timeout = 30
49
- @read_timeout = 80
53
+ @read_timeout = 90
50
54
  @ssl_ca_file = nil
51
55
  @ssl_ca_path = nil
52
56
  @ssl_cert_store = nil
57
+ @max_retry = 0
58
+ @retry_initial_delay = 2
59
+ @retry_max_delay = 32
53
60
 
54
61
  class << self
55
62
  attr_accessor :api_key, :api_base, :api_version, :connect_base, :uploads_base,
56
- :open_timeout, :read_timeout, :ssl_ca_file, :ssl_ca_path, :ssl_cert_store
63
+ :open_timeout, :read_timeout, :ssl_ca_file, :ssl_ca_path, :ssl_cert_store, :max_retry, :retry_initial_delay, :retry_max_delay
57
64
  end
58
65
 
59
66
  def self.api_url(url = '', api_base_url = nil)
60
67
  (api_base_url || @api_base) + url
61
68
  end
62
69
 
63
- def self.request(method, url, api_key, params = {}, headers = {}, api_base_url = nil, open_timeout = nil, read_timeout = nil, ssl_ca_file = nil, ssl_ca_path = nil, ssl_cert_store = nil)
70
+ def self.get_retry_delay(retry_count, retry_initial_delay, retry_max_delay)
71
+ # Get retry delay seconds.
72
+ # Based on "Exponential backoff with equal jitter" algorithm.
73
+ # https://aws.amazon.com/jp/blogs/architecture/exponential-backoff-and-jitter/
74
+
75
+ wait = [retry_max_delay, retry_initial_delay * 2 ** retry_count].min
76
+ random = Random.new()
77
+ (wait / 2) + (random.rand(wait / 2.0))
78
+ end
79
+
80
+ def self.request(method, url, api_key, params = {}, headers = {}, api_base_url = nil, open_timeout = nil, read_timeout = nil, ssl_ca_file = nil, ssl_ca_path = nil, ssl_cert_store = nil, max_retry = nil, retry_initial_delay= nil, retry_max_delay = nil)
64
81
  api_base_url ||= @api_base
65
82
  open_timeout ||= @open_timeout
66
83
  read_timeout ||= @read_timeout
67
84
  ssl_ca_file ||= @ssl_ca_file
68
85
  ssl_ca_path ||= @ssl_ca_path
69
86
  ssl_cert_store ||= @ssl_cert_store
87
+ max_retry ||= @max_retry
88
+ retry_initial_delay ||= @retry_initial_delay
89
+ retry_max_delay ||= @retry_max_delay
70
90
 
71
91
  unless api_key ||= @api_key
72
92
  raise AuthenticationError.new('No API key provided. ' \
@@ -107,6 +127,8 @@ module Payjp
107
127
  :ssl_ca_file => ssl_ca_file, :ssl_ca_path => ssl_ca_path,
108
128
  :ssl_cert_store => ssl_cert_store)
109
129
 
130
+ retry_count = 1
131
+
110
132
  begin
111
133
  # $stderr.puts request_opts
112
134
 
@@ -122,6 +144,12 @@ module Payjp
122
144
  raise
123
145
  end
124
146
  rescue RestClient::ExceptionWithResponse => e
147
+ if e.http_code == 429 and retry_count <= max_retry then
148
+ sleep get_retry_delay(retry_count, retry_initial_delay, retry_max_delay)
149
+ retry_count += 1
150
+ retry
151
+ end
152
+
125
153
  if rcode = e.http_code and rbody = e.http_body
126
154
  handle_api_error(rcode, rbody)
127
155
  else
@@ -239,6 +267,8 @@ module Payjp
239
267
  raise authentication_error error, rcode, rbody, error_obj
240
268
  when 402
241
269
  raise card_error error, rcode, rbody, error_obj
270
+ when 429
271
+ raise api_error error, rcode, rbody, error_obj
242
272
  else
243
273
  raise api_error error, rcode, rbody, error_obj
244
274
  end
@@ -266,11 +296,12 @@ module Payjp
266
296
  api_base_url = @api_base unless api_base_url
267
297
  connection_message = "Please check your internet connection and try again. " \
268
298
  "If this problem persists, you should check Payjp's service status at " \
269
- "https://twitter.com/payjpstatus, or let us know at support@pay.jp."
299
+ "https://status.pay.jp or let us know at support@pay.jp."
270
300
 
271
301
  case e
272
302
  when RestClient::RequestTimeout
273
- message = "Could not connect to Payjp (#{api_base_url}). #{connection_message}"
303
+ message = "Timed out over #{@read_timeout} sec. " \
304
+ "Check if your request successed or not."
274
305
 
275
306
  when RestClient::ServerBrokeConnection
276
307
  message = "The connection to the server (#{api_base_url}) broke before the " \
@@ -278,8 +309,7 @@ module Payjp
278
309
 
279
310
  when SocketError
280
311
  message = "Unexpected error communicating when trying to connect to Payjp. " \
281
- "You may be seeing this message because your DNS is not working. " \
282
- "To check, try running 'host pay.jp' from the command line."
312
+ "Your DNS may not work. Check 'host api.pay.jp' from the command line."
283
313
 
284
314
  else
285
315
  message = "Unexpected error communicating with Payjp. " \
data/payjp.gemspec CHANGED
@@ -23,5 +23,8 @@ Gem::Specification.new do |s|
23
23
  s.files = `git ls-files`.split("\n")
24
24
  s.test_files = `git ls-files -- test/*`.split("\n")
25
25
  s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
26
- s.require_paths = ['lib']
26
+ s.require_paths = ['lib']
27
+ s.metadata = {
28
+ "source_code_uri" => "https://github.com/payjp/payjp-ruby",
29
+ }
27
30
  end
@@ -411,6 +411,25 @@ module Payjp
411
411
 
412
412
  assert_equal true, rescued
413
413
  end
414
+
415
+ should "429s should raise a APIError of over capacity error code" do
416
+ response = test_response(test_over_capacity_error, 429)
417
+ @mock.expects(:get).once.raises(RestClient::ExceptionWithResponse.new(response, 429))
418
+
419
+ rescued = false
420
+ begin
421
+ Payjp::Customer.new("test_customer").refresh
422
+ assert false # shouldn't get here either
423
+ rescue Payjp::APIError => e # we don't use assert_raises because we want to examine e
424
+ rescued = true
425
+ assert e.is_a? Payjp::APIError
426
+ assert_equal(429, e.http_status)
427
+ assert_equal(true, !!e.http_body)
428
+ assert_equal("over_capacity", e.json_body[:error][:code])
429
+ end
430
+
431
+ assert_equal true, rescued
432
+ end
414
433
  end
415
434
 
416
435
  should 'save nothing if nothing changes' do
@@ -442,4 +461,120 @@ module Payjp
442
461
  end
443
462
  end
444
463
  end
464
+
465
+ class APIRequestorRetryTest < Test::Unit::TestCase
466
+
467
+ setup do
468
+ Payjp.max_retry = 0
469
+ Payjp.retry_initial_delay = 0.1
470
+ end
471
+
472
+ def mock_exceptions(error_codes, call_count)
473
+ exception_mock = nil
474
+ error_codes.with_index(1) { |code, id|
475
+ if id == 1
476
+ exception_mock = @mock.expects(:get).raises(RestClient::ExceptionWithResponse.new(test_response(test_api_error, code)))
477
+ else
478
+ exception_mock = exception_mock.then.raises(RestClient::ExceptionWithResponse.new(test_response(test_api_error, code)))
479
+ end
480
+ }
481
+ exception_mock.at_least(call_count)
482
+ end
483
+
484
+ context "checking retry" do
485
+ should "over capacity retry disabled" do
486
+ error_codes = [429, 599].to_enum
487
+ # returns 599 at 2nd try but max_retry 0 then retry disabled
488
+ mock_exceptions(error_codes, 1)
489
+ rescued = false
490
+
491
+ begin
492
+ Payjp::Charge.retrieve("test_charge")
493
+ rescue Payjp::APIError => e # we don't use assert_raises because we want to examine e
494
+ assert e.is_a? Payjp::APIError
495
+ assert_equal(429, e.http_status)
496
+ rescued = true
497
+ end
498
+ assert_equal true, rescued
499
+ end
500
+
501
+ should "no retry" do
502
+ Payjp.max_retry = 2
503
+ Payjp.retry_initial_delay = 0.1
504
+ error_codes = [599, 429, 429, 429].to_enum
505
+ # returns 599 at first try
506
+ mock_exceptions(error_codes, 1)
507
+ rescued = false
508
+
509
+ begin
510
+ Payjp::Charge.retrieve("test_charge")
511
+ rescue Payjp::APIError => e # we don't use assert_raises because we want to examine e
512
+ assert e.is_a? Payjp::APIError
513
+ assert_equal(599, e.http_status)
514
+ assert_equal(true, !!e.http_body)
515
+ rescued = true
516
+ end
517
+ assert_equal true, rescued
518
+ end
519
+
520
+ should "over capacity full retry" do
521
+ Payjp.max_retry = 2
522
+ Payjp.retry_initial_delay = 0.1
523
+ error_codes = [429, 429, 429, 429, 599].to_enum
524
+
525
+ # first try + 2 retries + unexpected 599
526
+ mock_exceptions(error_codes, 3)
527
+ rescued = false
528
+
529
+ begin
530
+ Payjp::Charge.retrieve("test_charge")
531
+ rescue Payjp::APIError => e # we don't use assert_raises because we want to examine e
532
+ assert e.is_a? Payjp::APIError
533
+ assert_equal(429, e.http_status)
534
+ rescued = true
535
+ end
536
+
537
+ assert_equal true, rescued
538
+ end
539
+
540
+ should "over capacity halfway of retries" do
541
+ Payjp.max_retry = 5
542
+ Payjp.retry_initial_delay = 0.1
543
+
544
+ error_codes = [429, 599, 429, 429, 429].to_enum
545
+ rescued = false
546
+
547
+ # returns not 429 status at 2nd try
548
+ mock_exceptions(error_codes, 2)
549
+ begin
550
+ Payjp::Charge.retrieve("test_charge")
551
+ rescue Payjp::APIError => e # we don't use assert_raises because we want to examine e
552
+ assert e.is_a? Payjp::APIError
553
+ assert_equal(599, e.http_status)
554
+ rescued = true
555
+ end
556
+
557
+ assert_equal true, rescued
558
+ end
559
+ end
560
+
561
+ context "retry interval" do
562
+ should "retry initial delay" do
563
+ retry_initial_delay = 2
564
+ retry_max_delay = 32
565
+
566
+ assert_equal(true, Payjp.get_retry_delay(0, retry_initial_delay, retry_max_delay).between?(1, 2))
567
+ assert_equal(true, Payjp.get_retry_delay(1, retry_initial_delay, retry_max_delay).between?(2, 4))
568
+ assert_equal(true, Payjp.get_retry_delay(2, retry_initial_delay, retry_max_delay).between?(4, 8))
569
+ # cap
570
+ assert_equal(true, Payjp.get_retry_delay(4, retry_initial_delay, retry_max_delay).between?(16, 32))
571
+ assert_equal(true, Payjp.get_retry_delay(10, retry_initial_delay, retry_max_delay).between?(16, 32))
572
+ end
573
+ end
574
+
575
+ teardown do
576
+ Payjp.max_retry = 0
577
+ Payjp.retry_initial_delay = 0.1
578
+ end
579
+ end
445
580
  end
@@ -0,0 +1,26 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ module Payjp
4
+ class BalanceTest < Test::Unit::TestCase
5
+ should "balances should be listable" do
6
+ @mock.expects(:get).once.returns(test_response(test_balance_array))
7
+ c = Payjp::Balance.all.data
8
+ assert c.is_a? Array
9
+ assert c[0].is_a? Payjp::Balance
10
+ end
11
+
12
+ should "retrieve should retrieve balance" do
13
+ @mock.expects(:get).once.returns(test_response(test_balance))
14
+ balance = Payjp::Balance.retrieve('ba_test_balance')
15
+ assert_equal 'ba_test_balance', balance.id
16
+ end
17
+
18
+ should "balances should not be deletable" do
19
+ assert_raises NoMethodError do
20
+ @mock.expects(:get).once.returns(test_response(test_balance))
21
+ balance = Payjp::Balance.retrieve('ba_test_balance')
22
+ balance.delete
23
+ end
24
+ end
25
+ end
26
+ end
@@ -91,5 +91,17 @@ module Payjp
91
91
  c.reauth
92
92
  assert_equal expired_at.to_i, c.expired_at
93
93
  end
94
+
95
+ should "charges should be three_d_secure finishable" do
96
+ @mock.expects(:get).never
97
+ @mock.expects(:post).with do |url, api_key, params|
98
+ url == "#{Payjp.api_base}/v1/charges/test_charge/tds_finish" && api_key.nil? && CGI.parse(params) == {}
99
+ end.once.returns(test_response({ :id => "test_charge", :paid => true, :captured => true }))
100
+
101
+ c = Payjp::Charge.new("test_charge")
102
+ c.tds_finish
103
+ assert c.paid
104
+ assert c.captured
105
+ end
94
106
  end
95
107
  end
@@ -0,0 +1,33 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ module Payjp
4
+ class StatementTest < Test::Unit::TestCase
5
+ should "statement should be listable" do
6
+ @mock.expects(:get).once.returns(test_response(test_statement_array))
7
+ statements = Payjp::Statement.all.data
8
+ assert statements.is_a? Array
9
+ assert statements[0].is_a? Payjp::Statement
10
+ end
11
+
12
+ should "be retrievable" do
13
+ @mock.expects(:get).once.returns(test_response(test_statement))
14
+ statement = Payjp::Statement.retrieve('st_test')
15
+ assert statement.is_a? Payjp::Statement
16
+ assert_equal 'st_test', statement.id
17
+ assert_equal 'statement', statement.object
18
+ assert statement.to_hash.has_key?(:items)
19
+ assert statement.items[0].to_hash.has_key?(:amount)
20
+ assert statement.items[0].to_hash.has_key?(:name)
21
+ assert statement.items[0].to_hash.has_key?(:subject)
22
+ assert statement.items[0].to_hash.has_key?(:tax_rate)
23
+ end
24
+
25
+ should "statement_urls should be callable" do
26
+ @mock.expects(:get).never
27
+ @mock.expects(:post).once.returns(test_response({ :object => "statement_url", :url => 'https://pay.jp/_/statements/8f9ec721bc734dbcxxxxxxxxxxxxxxxx', :expires => 1476676539 }))
28
+ c = Payjp::Statement.new('st_test')
29
+ response = c.statement_urls()
30
+ assert_equal response[:url], 'https://pay.jp/_/statements/8f9ec721bc734dbcxxxxxxxxxxxxxxxx'
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,42 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ module Payjp
4
+ class TenantTest < Test::Unit::TestCase
5
+ should "tenants should be listable" do
6
+ @mock.expects(:get).once.returns(test_response(test_tenant_array))
7
+ c = Payjp::Tenant.all.data
8
+ assert c.is_a? Array
9
+ assert c[0].is_a? Payjp::Tenant
10
+ end
11
+
12
+ should "tenants should be deletable" do
13
+ @mock.expects(:delete).once.returns(test_response(test_tenant))
14
+ c = Payjp::Tenant.new("test_tenant")
15
+ c.delete
16
+ end
17
+
18
+ should "tenants should be updateable" do
19
+ @mock.expects(:get).once.returns(test_response(test_tenant({ :name => "foo" })))
20
+ @mock.expects(:post).once.returns(test_response(test_tenant({ :name => "bar" })))
21
+ c = Payjp::Tenant.new("test_tenant").refresh
22
+ assert_equal "foo", c.name
23
+ c.name = "bar"
24
+ c.save
25
+ assert_equal "bar", c.name
26
+ end
27
+
28
+ should "create should return a new tenant" do
29
+ @mock.expects(:post).once.returns(test_response(test_tenant(:id => 'test_tenant1')))
30
+ c = Payjp::Tenant.create(:id => 'test_tenant1')
31
+ assert_equal "test_tenant1", c.id
32
+ end
33
+
34
+ should "create_application_urls should be callable" do
35
+ @mock.expects(:get).never
36
+ @mock.expects(:post).once.returns(test_response({ :object => "application_url", :url => 'https://pay.jp/_/applications/start/c24368137e384aa9xxxxxxxxxxxxxxxx', :expires => 1476676539 }))
37
+ c = Payjp::Tenant.new('test_tenant')
38
+ response = c.create_application_urls()
39
+ assert_equal response[:url], 'https://pay.jp/_/applications/start/c24368137e384aa9xxxxxxxxxxxxxxxx'
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,26 @@
1
+ require File.expand_path('../../test_helper', __FILE__)
2
+
3
+ module Payjp
4
+ class TermTest < Test::Unit::TestCase
5
+ should "terms should be listable" do
6
+ @mock.expects(:get).once.returns(test_response(test_term_array))
7
+ c = Payjp::Term.all.data
8
+ assert c.is_a? Array
9
+ assert c[0].is_a? Payjp::Term
10
+ end
11
+
12
+ should "retrieve should retrieve term" do
13
+ @mock.expects(:get).once.returns(test_response(test_term))
14
+ term = Payjp::Term.retrieve('tm_test_term')
15
+ assert_equal 'tm_test_term', term.id
16
+ end
17
+
18
+ should "terms should not be deletable" do
19
+ assert_raises NoMethodError do
20
+ @mock.expects(:get).once.returns(test_response(test_term))
21
+ term = Payjp::Term.retrieve('tm_test_term')
22
+ term.delete
23
+ end
24
+ end
25
+ end
26
+ end
data/test/test_data.rb CHANGED
@@ -235,7 +235,9 @@ module Payjp
235
235
  :charge_gross => 1000,
236
236
  :net => 1000,
237
237
  :refund_amount => 0,
238
- :refund_count => 0
238
+ :refund_count => 0,
239
+ :dispute_amount => 0,
240
+ :dispute_count => 0
239
241
  },
240
242
  :metadata => {}
241
243
  }.merge(params)
@@ -250,6 +252,35 @@ module Payjp
250
252
  }
251
253
  end
252
254
 
255
+ def test_tenant(params = {})
256
+ {
257
+ :created => 1433127983,
258
+ :name => "test",
259
+ :id => "test",
260
+ :livemode => false,
261
+ :metadata => nil,
262
+ :object => "tenant",
263
+ :platform_fee_rate => "10.15",
264
+ :payjp_fee_included => false,
265
+ :minimum_transfer_amount => 1000,
266
+ :bank_account_number => "0001000",
267
+ :bank_branch_code => "000",
268
+ :bank_code => "0000",
269
+ :bank_account_holder_name => "ヤマダ タロウ",
270
+ :bank_account_type => "普通",
271
+ :bank_account_status => "pending"
272
+ }.merge(params)
273
+ end
274
+
275
+ def test_tenant_array
276
+ {
277
+ :count => 3,
278
+ :data => [test_tenant, test_tenant, test_tenant],
279
+ :object => 'list',
280
+ :url => '/v1/tenants'
281
+ }
282
+ end
283
+
253
284
  def test_invalid_api_key_error
254
285
  {
255
286
  :error => {
@@ -287,5 +318,112 @@ module Payjp
287
318
  }
288
319
  }
289
320
  end
321
+
322
+ def test_over_capacity_error
323
+ {
324
+ :error => {
325
+ :code => "over_capacity",
326
+ :type => "api_error"
327
+ }
328
+ }
329
+ end
330
+
331
+ def test_statement(params = {})
332
+ {
333
+ :created => 1695620296,
334
+ :id => "st_test",
335
+ :items => [
336
+ {
337
+ :amount => 282358654,
338
+ :name => "売上",
339
+ :subject => "gross_sales",
340
+ :tax_rate => "0.00"
341
+ },
342
+ {
343
+ :amount => -65699624,
344
+ :name => "返金",
345
+ :subject => "gross_refund",
346
+ :tax_rate => "0.00"
347
+ },
348
+ {
349
+ :amount => -7054912,
350
+ :name => "決済手数料",
351
+ :subject => "fee",
352
+ :tax_rate => "0.10"
353
+ },
354
+ {
355
+ :amount => 1644315,
356
+ :name => "返金による手数料返還",
357
+ :subject => "refund_fee_offset",
358
+ :tax_rate => "0.10"
359
+ }
360
+ ],
361
+ :object => "statement",
362
+ :title => nil,
363
+ :tenant_id => nil,
364
+ :updated => 1695892351
365
+ }.merge(params)
366
+ end
367
+
368
+ def test_statement_array
369
+ {
370
+ :count => 2,
371
+ :data => [test_statement, test_statement],
372
+ :object => 'list',
373
+ :url => '/v1/statements'
374
+ }
375
+ end
376
+
377
+ def test_term_array
378
+ {
379
+ :count => 3,
380
+ :data => [test_term, test_term, test_term],
381
+ :object => 'list',
382
+ :url => '/v1/terms'
383
+ }
384
+ end
385
+
386
+ def test_term(params = {})
387
+ {
388
+ :id => "tm_test_term",
389
+ :livemode => false,
390
+ :object => "term",
391
+ :charge_count => 158,
392
+ :refund_count => 25,
393
+ :dispute_count => 2,
394
+ :end_at => 1439650800,
395
+ :start_at => 1438354800
396
+ }.merge(params)
397
+ end
398
+
399
+ def test_balance_array
400
+ {
401
+ :count => 3,
402
+ :data => [test_balance, test_balance, test_balance],
403
+ :object => 'list',
404
+ :url => '/v1/terms'
405
+ }
406
+ end
407
+
408
+ def test_balance(params = {})
409
+ {
410
+ :created => 1438354800,
411
+ :id => 'ba_test_balance',
412
+ :livemode => false,
413
+ :net => 1000,
414
+ :object => 'balance',
415
+ :state => 'collecting',
416
+ :tenant_id => nil,
417
+ :statements => {
418
+ :count => 2,
419
+ :data => [test_statement,test_statement],
420
+ :object => 'list',
421
+ :url => '/v1/statements'
422
+ },
423
+ :closed => false,
424
+ :due_date => nil,
425
+ :bank_info => nil
426
+ }.merge(params)
427
+ end
290
428
  end
291
429
  end
metadata CHANGED
@@ -1,103 +1,103 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: payjp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - PAY.JP
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-25 00:00:00.000000000 Z
11
+ date: 2024-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '2.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: mocha
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: 1.2.1
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
40
  version: 1.2.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: activesupport
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - <
45
+ - - "<"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '5.0'
48
- - - ~>
48
+ - - "~>"
49
49
  - !ruby/object:Gem::Version
50
50
  version: 4.2.7
51
51
  type: :development
52
52
  prerelease: false
53
53
  version_requirements: !ruby/object:Gem::Requirement
54
54
  requirements:
55
- - - <
55
+ - - "<"
56
56
  - !ruby/object:Gem::Version
57
57
  version: '5.0'
58
- - - ~>
58
+ - - "~>"
59
59
  - !ruby/object:Gem::Version
60
60
  version: 4.2.7
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: test-unit
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
- - - ~>
65
+ - - "~>"
66
66
  - !ruby/object:Gem::Version
67
67
  version: 3.2.2
68
68
  type: :development
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
- - - ~>
72
+ - - "~>"
73
73
  - !ruby/object:Gem::Version
74
74
  version: 3.2.2
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: rake
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - ~>
79
+ - - "~>"
80
80
  - !ruby/object:Gem::Version
81
81
  version: 11.3.0
82
82
  type: :development
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
- - - ~>
86
+ - - "~>"
87
87
  - !ruby/object:Gem::Version
88
88
  version: 11.3.0
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: bundler
91
91
  requirement: !ruby/object:Gem::Requirement
92
92
  requirements:
93
- - - '>='
93
+ - - ">="
94
94
  - !ruby/object:Gem::Version
95
95
  version: 1.7.6
96
96
  type: :development
97
97
  prerelease: false
98
98
  version_requirements: !ruby/object:Gem::Requirement
99
99
  requirements:
100
- - - '>='
100
+ - - ">="
101
101
  - !ruby/object:Gem::Version
102
102
  version: 1.7.6
103
103
  description: PAY.JP makes it way easier and less expensive to accept payments.
@@ -107,15 +107,16 @@ executables: []
107
107
  extensions: []
108
108
  extra_rdoc_files: []
109
109
  files:
110
- - .gitignore
111
- - .rubocop.yml
112
- - .rubocop_todo.yml
113
- - .travis.yml
110
+ - ".github/workflows/ruby-publish.yml"
111
+ - ".github/workflows/test.yml"
112
+ - ".gitignore"
113
+ - ".rubocop.yml"
114
+ - ".rubocop_todo.yml"
114
115
  - CONTRIBUTORS
115
116
  - Gemfile
116
117
  - History.txt
117
118
  - LICENSE
118
- - README.rdoc
119
+ - README.md
119
120
  - Rakefile
120
121
  - lib/payjp.rb
121
122
  - lib/payjp/account.rb
@@ -125,6 +126,7 @@ files:
125
126
  - lib/payjp/api_operations/request.rb
126
127
  - lib/payjp/api_operations/update.rb
127
128
  - lib/payjp/api_resource.rb
129
+ - lib/payjp/balance.rb
128
130
  - lib/payjp/card.rb
129
131
  - lib/payjp/charge.rb
130
132
  - lib/payjp/customer.rb
@@ -138,7 +140,10 @@ files:
138
140
  - lib/payjp/list_object.rb
139
141
  - lib/payjp/payjp_object.rb
140
142
  - lib/payjp/plan.rb
143
+ - lib/payjp/statement.rb
141
144
  - lib/payjp/subscription.rb
145
+ - lib/payjp/tenant.rb
146
+ - lib/payjp/term.rb
142
147
  - lib/payjp/token.rb
143
148
  - lib/payjp/transfer.rb
144
149
  - lib/payjp/util.rb
@@ -146,6 +151,7 @@ files:
146
151
  - payjp.gemspec
147
152
  - test/payjp/account_test.rb
148
153
  - test/payjp/api_resource_test.rb
154
+ - test/payjp/balance_test.rb
149
155
  - test/payjp/charge_test.rb
150
156
  - test/payjp/customer_card_test.rb
151
157
  - test/payjp/customer_test.rb
@@ -154,7 +160,10 @@ files:
154
160
  - test/payjp/metadata_test.rb
155
161
  - test/payjp/payjp_object_test.rb
156
162
  - test/payjp/plan_test.rb
163
+ - test/payjp/statement_test.rb
157
164
  - test/payjp/subscription_test.rb
165
+ - test/payjp/tenant_test.rb
166
+ - test/payjp/term_test.rb
158
167
  - test/payjp/token_test.rb
159
168
  - test/payjp/transfer_test.rb
160
169
  - test/payjp/util_test.rb
@@ -163,30 +172,31 @@ files:
163
172
  homepage: https://pay.jp
164
173
  licenses:
165
174
  - MIT
166
- metadata: {}
175
+ metadata:
176
+ source_code_uri: https://github.com/payjp/payjp-ruby
167
177
  post_install_message:
168
178
  rdoc_options: []
169
179
  require_paths:
170
180
  - lib
171
181
  required_ruby_version: !ruby/object:Gem::Requirement
172
182
  requirements:
173
- - - '>='
183
+ - - ">="
174
184
  - !ruby/object:Gem::Version
175
185
  version: '0'
176
186
  required_rubygems_version: !ruby/object:Gem::Requirement
177
187
  requirements:
178
- - - '>='
188
+ - - ">="
179
189
  - !ruby/object:Gem::Version
180
190
  version: '0'
181
191
  requirements: []
182
- rubyforge_project:
183
- rubygems_version: 2.0.14.1
192
+ rubygems_version: 3.1.6
184
193
  signing_key:
185
194
  specification_version: 4
186
195
  summary: Ruby bindings for the Payjp API
187
196
  test_files:
188
197
  - test/payjp/account_test.rb
189
198
  - test/payjp/api_resource_test.rb
199
+ - test/payjp/balance_test.rb
190
200
  - test/payjp/charge_test.rb
191
201
  - test/payjp/customer_card_test.rb
192
202
  - test/payjp/customer_test.rb
@@ -195,7 +205,10 @@ test_files:
195
205
  - test/payjp/metadata_test.rb
196
206
  - test/payjp/payjp_object_test.rb
197
207
  - test/payjp/plan_test.rb
208
+ - test/payjp/statement_test.rb
198
209
  - test/payjp/subscription_test.rb
210
+ - test/payjp/tenant_test.rb
211
+ - test/payjp/term_test.rb
199
212
  - test/payjp/token_test.rb
200
213
  - test/payjp/transfer_test.rb
201
214
  - test/payjp/util_test.rb
data/.travis.yml DELETED
@@ -1,10 +0,0 @@
1
- language: ruby
2
-
3
- rvm:
4
- - 2.0.0
5
- - 2.1
6
- - 2.2
7
- - 2.3.0
8
- - jruby-9.0.5.0
9
-
10
- sudo: false
data/README.rdoc DELETED
@@ -1,37 +0,0 @@
1
- = PAY.JP for Ruby
2
-
3
- == Documentation
4
-
5
- {PAY.JP API Docs}[https://pay.jp/docs/api/]
6
-
7
- == Installation
8
-
9
- You don't need this source code unless you want to modify the gem. If
10
- you just want to use the Payjp Ruby bindings, you should run:
11
-
12
- gem install payjp
13
-
14
- If you want to build the gem from source:
15
-
16
- gem build payjp.gemspec
17
-
18
- == Requirements
19
-
20
- * Ruby 2.0.0 or above.
21
-
22
- * rest-client
23
-
24
- == Bundler
25
-
26
- If you are installing via bundler, you should be sure to use the https
27
- rubygems source in your Gemfile, as any gems fetched over http could potentially be
28
- compromised in transit and alter the code of gems fetched securely over https:
29
-
30
- source 'https://rubygems.org'
31
-
32
- gem 'rails'
33
- gem 'payjp'
34
-
35
- == Development
36
-
37
- Test cases can be run with: `bundle exec rake test`