payjp 0.0.6 → 0.0.14

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
- 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`