payload-api 0.4.0 → 0.5.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
  SHA256:
3
- metadata.gz: c6a65380dc908d716ddb1642ecb6bab391061c469ffa9951b80d3db94e84b08d
4
- data.tar.gz: 77978473db8ca858d60db59155625b3133e5d8470fa69ff6a76ec497c086c17a
3
+ metadata.gz: 66c7eb5c0125eb3e66a5800851c6e66e42ae36138a2b89516b2ae8a823cacc7d
4
+ data.tar.gz: 602f23d391904acdb9ddf3540990692f8f54284746d3bba5eb528827f2f802da
5
5
  SHA512:
6
- metadata.gz: '09dce62dabb4cd5d51432adec32190ffb4b0f9a924c3794c0cef3d009c6e0d73897d9d58ca1d8417a85709ca903581fbb444ad66dab3951b27b8bf2ed0e0198d'
7
- data.tar.gz: e2d546eef549863a7c3da77c9c6e4ddb5446fa19cc93d854de7109530cff8645a51af2bc46f6a9095bd7b629fe99f464a30848262c459d3899d91d2eddc3ff7a
6
+ metadata.gz: 19b0346676cab8cbd11a997fbb30f2a9ccec35eb16bfe7905da763efc6f5b7efc27002ac828ff0b14041e284bdd10d0cbc093dbb3d09350dd08bb5cd82bfa1af
7
+ data.tar.gz: 7abac9292dcc52fe334f4182f59d6c4253242451a5f3e4aec7997399a6469c56caadf3862b511529d08b5e65c5779764ad868b2e06134266500deedbfa0e73f4
@@ -20,6 +20,8 @@ jobs:
20
20
  ruby-version: 3.0.1
21
21
 
22
22
  - name: Run RSpec tests
23
+ env:
24
+ TEST_SECRET_KEY: ${{ secrets.API_KEY }}
23
25
  run: |
24
26
  gem install rspec
25
27
  rspec spec
data/README.md CHANGED
@@ -7,13 +7,13 @@ A RubyGem for integrating [Payload](https://payload.com).
7
7
  To install using [Bundler](https://bundler.io):
8
8
 
9
9
  ```ruby
10
- gem 'payload-api', '~> 0.2.4'
10
+ gem 'payload-api', '~> 0.5.0'
11
11
  ```
12
12
 
13
13
  To install using gem:
14
14
 
15
15
  ```bash
16
- gem install payload
16
+ gem install payload-api
17
17
  ```
18
18
 
19
19
  ## Get Started
@@ -34,6 +34,27 @@ require 'payload'
34
34
  Payload.api_key = 'secret_key_3bW9JMZtPVDOfFNzwRdfE'
35
35
  ```
36
36
 
37
+ ### API Versioning
38
+
39
+ The Payload API supports multiple versions. You can specify which version to use when making requests:
40
+
41
+ ```ruby
42
+ require 'payload'
43
+ Payload.api_key = 'secret_key_3bW9JMZtPVDOfFNzwRdfE'
44
+ Payload.api_version = 'v2' # Use API v2
45
+ ```
46
+
47
+ Or with sessions:
48
+
49
+ ```ruby
50
+ pl = Payload::Session.new(
51
+ 'secret_key_3bW9JMZtPVDOfFNzwRdfE',
52
+ api_version: 'v2'
53
+ )
54
+ ```
55
+
56
+ API v2 introduces new objects including `Profile`, `Intent`, `Entity`, `Transfer`, `ProcessingAgreement`, and more. See the [Payload API Documentation](https://docs.payload.com) for details on API versions.
57
+
37
58
  ### Creating an Object
38
59
 
39
60
  Interfacing with the Payload API is done primarily through Payload Objects. Below is an example of
@@ -29,6 +29,10 @@ module Payload
29
29
  def get(id)
30
30
  return @cls.get(id, :session => @session)
31
31
  end
32
+
33
+ def select(*args, **data)
34
+ @cls.select(*args, **data, session: @session)
35
+ end
32
36
 
33
37
  end
34
38
 
@@ -158,5 +162,9 @@ module Payload
158
162
  serialized.merge!(@data)
159
163
  return serialized.to_json(*args)
160
164
  end
165
+
166
+ def respond_to_missing?(name, include_private = false)
167
+ @data && @data.key?(name.to_s) || super
168
+ end
161
169
  end
162
170
  end
@@ -31,6 +31,7 @@ module Payload
31
31
  end
32
32
 
33
33
  def all()
34
+ # TODO: I don't think this applies the @poly variable as intended?
34
35
  return self._request('Get')
35
36
  end
36
37
 
@@ -162,6 +163,10 @@ module Payload
162
163
  request.add_field('Content-Type', 'application/json')
163
164
  end
164
165
 
166
+ if @session.api_version
167
+ request.add_field('X-API-Version', @session.api_version)
168
+ end
169
+
165
170
  response = self._execute_request(http, request)
166
171
 
167
172
  begin
@@ -170,7 +175,7 @@ module Payload
170
175
  if response.code == '500'
171
176
  raise Payload::InternalError.new
172
177
  else
173
- raise Place::UnknownResponse.new
178
+ raise Payload::UnknownResponse.new
174
179
  end
175
180
  end
176
181
 
@@ -178,6 +183,7 @@ module Payload
178
183
  if data['object'] == 'list'
179
184
  return data['values'].map do |obj|
180
185
  cls = Payload::get_cls(obj)
186
+ cls = @cls if cls.nil? && !@cls.nil?
181
187
  if cls.nil?
182
188
  obj
183
189
  else
@@ -186,7 +192,13 @@ module Payload
186
192
  end
187
193
  end
188
194
  else
189
- return Payload::get_cls(data).new(data, @session)
195
+ cls = Payload::get_cls(data)
196
+ cls = @cls if cls.nil? && !@cls.nil?
197
+ if cls.nil?
198
+ return data
199
+ else
200
+ return cls.new(data, @session)
201
+ end
190
202
  end
191
203
  else
192
204
  for error in Payload::subclasses(Payload::PayloadError)
@@ -2,14 +2,14 @@ require 'payload/arm/request'
2
2
 
3
3
 
4
4
  module Payload
5
-
6
5
  class Session
7
- attr_accessor :api_key, :api_url
8
-
9
- def initialize(api_key, api_url=nil)
10
- @api_key = api_key
11
- @api_url = api_url || Payload.URL
6
+ attr_accessor :api_key, :api_url, :api_version
12
7
 
8
+ def initialize(api_key = nil, api_url = nil, api_version = nil, **kwargs)
9
+ @api_key = kwargs[:api_key] || api_key
10
+ @api_url = kwargs[:api_url] || api_url || Payload.URL
11
+ @api_version = kwargs[:api_version] || api_version || Payload.api_version
12
+
13
13
  Payload.constants.each do |c|
14
14
  val = Payload.const_get(c)
15
15
  if val.is_a?(Class) && val < Payload::ARMObject
@@ -18,18 +18,6 @@ module Payload
18
18
  @spec = { 'object' => 'account' }
19
19
  end
20
20
 
21
- class Customer < ARMObject
22
- @spec = { 'object' => 'customer' }
23
- end
24
-
25
- class ProcessingAccount < ARMObject
26
- @spec = { 'object' => 'processing_account' }
27
- end
28
-
29
- class Org < ARMObject
30
- @spec = { 'object' => 'org', 'endpoint' => '/account/orgs' }
31
- end
32
-
33
21
  class Transaction < ARMObject
34
22
  @spec = { 'object' => 'transaction' }
35
23
  end
@@ -74,6 +62,19 @@ module Payload
74
62
  @spec = { 'object' => 'invoice' }
75
63
  end
76
64
 
65
+ class PaymentActivation < ARMObject
66
+ @spec = { 'object' => 'payment_activation' }
67
+ end
68
+
69
+ class Webhook < ARMObject
70
+ @spec = { 'object' => 'webhook' }
71
+ end
72
+
73
+ class PaymentLink < ARMObject
74
+ @spec = { 'object' => 'payment_link' }
75
+ end
76
+
77
+ # V1 objects
77
78
  class LineItem < ARMObject
78
79
  @spec = { 'object' => 'line_item' }
79
80
  end
@@ -88,15 +89,69 @@ module Payload
88
89
  @poly = { 'entry_type' => 'payment' }
89
90
  end
90
91
 
91
- class PaymentActivation < ARMObject
92
- @spec = { 'object' => 'payment_activation' }
92
+ class Customer < ARMObject
93
+ @spec = { 'object' => 'customer' }
93
94
  end
94
95
 
95
- class Webhook < ARMObject
96
- @spec = { 'object' => 'webhook' }
96
+ class ProcessingAccount < ARMObject
97
+ @spec = { 'object' => 'processing_account' }
98
+ end
99
+
100
+ class Org < ARMObject
101
+ @spec = { 'object' => 'org', 'endpoint' => '/account/orgs' }
97
102
  end
98
103
 
99
- class PaymentLink < ARMObject
100
- @spec = { 'object' => 'payment_link' }
104
+ # V2 objects
105
+ class InvoiceItem < ARMObject
106
+ @spec = { 'object' => 'invoice_item' }
107
+ end
108
+
109
+ class PaymentAllocation < ARMObject
110
+ @spec = { 'object' => 'payment_allocation' }
111
+ end
112
+
113
+ class Profile < ARMObject
114
+ @spec = { 'object' => 'profile' }
115
+ end
116
+
117
+ class BillingItem < ARMObject
118
+ @spec = { 'object' => 'billing_item' }
119
+ end
120
+
121
+ class Intent < ARMObject
122
+ @spec = { 'object' => 'intent' }
123
+ end
124
+
125
+ class Entity < ARMObject
126
+ @spec = { 'object' => 'entity' }
101
127
  end
128
+
129
+ class Stakeholder < ARMObject
130
+ @spec = { 'object' => 'stakeholder' }
131
+ end
132
+
133
+ class ProcessingAgreement < ARMObject
134
+ @spec = { 'object' => 'processing_agreement' }
135
+ end
136
+
137
+ class Transfer < ARMObject
138
+ @spec = { 'object' => 'transfer' }
139
+ end
140
+
141
+ class TransactionOperation < ARMObject
142
+ @spec = { 'object' => 'transaction_operation' }
143
+ end
144
+
145
+ class CheckFront < ARMObject
146
+ @spec = { 'object' => 'check_front' }
147
+ end
148
+
149
+ class CheckBack < ARMObject
150
+ @spec = { 'object' => 'check_back' }
151
+ end
152
+
153
+ class ProcessingRule < ARMObject
154
+ @spec = { 'object' => 'processing_rule' }
155
+ end
156
+
102
157
  end
@@ -1,3 +1,3 @@
1
1
  module Payload
2
- VERSION = '0.4.0'
2
+ VERSION = '0.5.0'
3
3
  end
data/lib/payload.rb CHANGED
@@ -3,8 +3,8 @@ require "payload/objects"
3
3
  require "payload/arm/session"
4
4
 
5
5
  module Payload
6
- @URL = "https://api.payload.com"
7
-
6
+ @URL = "https://api.payload.com"
7
+
8
8
  class << self
9
9
  def api_key=(value)
10
10
  session.api_key = value
@@ -22,15 +22,24 @@ module Payload
22
22
  session.api_url
23
23
  end
24
24
 
25
+ def api_version=(version)
26
+ @api_version = version
27
+ @session = nil
28
+ end
29
+
30
+ def api_version
31
+ @api_version
32
+ end
33
+
25
34
  def URL
26
35
  @URL
27
36
  end
28
37
 
29
38
  private
30
39
 
31
- def session
32
- @session ||= Payload::Session.new(nil, @URL)
33
- end
40
+ def session
41
+ @session ||= Payload::Session.new(nil, @URL)
42
+ end
34
43
  end
35
44
 
36
45
  def self.create(objects)
@@ -44,4 +53,5 @@ module Payload
44
53
  def self.delete(objects)
45
54
  return Payload::ARMRequest.new().delete_all(objects)
46
55
  end
56
+
47
57
  end
@@ -0,0 +1,19 @@
1
+ require 'payload'
2
+ require 'payload/arm/object'
3
+ require_relative '../../support/helpers'
4
+
5
+ RSpec.describe 'Access Token Integration Tests' do
6
+ include_context 'test helpers'
7
+
8
+ let(:session) { Payload::Session.new(Payload.api_key, Payload.api_url, 1) }
9
+
10
+ describe 'Access Token' do
11
+ it 'creates a client token' do
12
+ client_token = session.ClientToken.create
13
+ expect(client_token.status).to eq('active')
14
+ expect(client_token.type).to eq('client')
15
+ expect(client_token.environ).to eq('test')
16
+ end
17
+ end
18
+ end
19
+
@@ -0,0 +1,97 @@
1
+ require 'payload'
2
+ require 'payload/arm/object'
3
+ require_relative '../../support/helpers'
4
+
5
+ RSpec.describe 'Account Integration Tests - V1' do
6
+ include_context 'test helpers'
7
+
8
+ let(:session) { Payload::Session.new(Payload.api_key, Payload.api_url, 1) }
9
+ let(:h) { V1Helpers.new(session) }
10
+
11
+ describe 'Customer Account' do
12
+ it 'creates a customer account' do
13
+ customer_account = session.Customer.create(name: 'Test', email: 'test@example.com')
14
+ expect(customer_account.id).to be_truthy
15
+ end
16
+
17
+ it 'deletes a customer account' do
18
+ cust_account = session.Customer.create(name: 'Test', email: 'test@example.com')
19
+ cust_account.delete
20
+
21
+ expect {
22
+ session.Customer.get(cust_account.id)
23
+ }.to raise_error(Payload::NotFound)
24
+ end
25
+
26
+ it 'creates multiple accounts' do
27
+ rand_email1 = (0...5).map { ('a'..'z').to_a[rand(26)] }.join + '@example.com'
28
+ rand_email2 = (0...5).map { ('a'..'z').to_a[rand(26)] }.join + '@example.com'
29
+
30
+ name1 = 'Matt Perez'
31
+ name2 = 'Andrea Kearney'
32
+
33
+ accounts_to_create = [
34
+ session.Customer.new(email: rand_email1, name: name1),
35
+ session.Customer.new(email: rand_email2, name: name2)
36
+ ]
37
+ session.create(accounts_to_create)
38
+
39
+ get_account_1 = session.Customer.filter_by(email: rand_email1).all[0]
40
+ get_account_2 = session.Customer.filter_by(email: rand_email2).all[0]
41
+
42
+ expect(get_account_1).to be_truthy
43
+ expect(get_account_2).to be_truthy
44
+ end
45
+
46
+ it 'gets a processing account' do
47
+ proc_account = h.create_processing_account
48
+ retrieved = session.ProcessingAccount.get(proc_account.id)
49
+ expect(retrieved).to be_truthy
50
+ expect(retrieved.status).to eq('pending')
51
+ end
52
+
53
+ it 'pages and orders results' do
54
+ accounts_to_create = [
55
+ session.Customer.new(email: 'account1@example.com', name: 'Randy Robson'),
56
+ session.Customer.new(email: 'account2@example.com', name: 'Brandy Bobson'),
57
+ session.Customer.new(email: 'account3@example.com', name: 'Mandy Johnson')
58
+ ]
59
+ session.create(accounts_to_create)
60
+ customers = session.Customer.filter_by(order_by: 'created_at', limit: 3, offset: 1).all
61
+
62
+ expect(customers.length).to eq(3)
63
+ require 'time'
64
+ expect(Time.parse(customers[0].created_at)).to be <= Time.parse(customers[1].created_at)
65
+ expect(Time.parse(customers[1].created_at)).to be <= Time.parse(customers[2].created_at)
66
+ end
67
+
68
+ it 'updates a customer' do
69
+ cust_account = session.Customer.create(name: 'Test', email: 'test@example.com')
70
+ cust_account.update(email: 'test2@example.com')
71
+ expect(cust_account.email).to eq('test2@example.com')
72
+ end
73
+
74
+ it 'updates multiple accounts' do
75
+ customer_account_1 = session.Customer.create(name: 'Brandy', email: 'test1@example.com')
76
+ customer_account_2 = session.Customer.create(name: 'Sandy', email: 'test2@example.com')
77
+ updated_accounts = session.update([
78
+ [customer_account_1, { email: 'brandy@example.com' }],
79
+ [customer_account_2, { email: 'sandy@example.com' }]
80
+ ])
81
+
82
+ expect(updated_accounts[0].email).to eq('brandy@example.com')
83
+ expect(updated_accounts[1].email).to eq('sandy@example.com')
84
+ end
85
+
86
+ it 'gets a customer' do
87
+ cust_account = session.Customer.create(name: 'Test', email: 'test@example.com')
88
+ expect(session.Customer.get(cust_account.id)).to be_truthy
89
+ end
90
+
91
+ it 'selects customer attributes' do
92
+ cust_account = session.Customer.create(name: 'Test', email: 'test@example.com')
93
+ selected = session.Customer.select('id').get(cust_account.id)
94
+ expect(selected['id']).to eq(cust_account.id)
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,54 @@
1
+ require 'payload'
2
+ require 'payload/arm/object'
3
+ require_relative '../../support/helpers'
4
+
5
+ RSpec.describe 'Billing Integration Tests - V1' do
6
+ include_context 'test helpers'
7
+
8
+ let(:session) { Payload::Session.new(Payload.api_key, Payload.api_url, 1) }
9
+ let(:h) { V1Helpers.new(session) }
10
+
11
+ describe 'Billing Schedule' do
12
+ let(:billing_schedule) do
13
+ proc_account = h.create_processing_account
14
+ customer_account = h.create_customer_account
15
+ session.BillingSchedule.create(
16
+ start_date: '2019-01-01',
17
+ end_date: '2019-12-31',
18
+ recurring_frequency: 'monthly',
19
+ type: 'subscription',
20
+ customer_id: customer_account.id,
21
+ processing_id: proc_account.id,
22
+ charges: [
23
+ {
24
+ type: 'option_1',
25
+ amount: 39.99
26
+ }
27
+ ]
28
+ )
29
+ end
30
+
31
+ it 'creates a billing schedule' do
32
+ schedule = billing_schedule
33
+ expect(schedule.charges[0]['amount']).to eq(39.99)
34
+ end
35
+
36
+ it 'updates billing schedule frequency' do
37
+ schedule = billing_schedule
38
+ expect(schedule.charges[0]['amount']).to eq(39.99)
39
+
40
+ schedule.update(recurring_frequency: 'quarterly')
41
+ expect(schedule.recurring_frequency).to eq('quarterly')
42
+ end
43
+
44
+ it 'deletes a billing schedule' do
45
+ schedule = billing_schedule
46
+ schedule.delete
47
+
48
+ expect {
49
+ session.BillingSchedule.get(schedule.id)
50
+ }.to raise_error(Payload::NotFound)
51
+ end
52
+ end
53
+ end
54
+
@@ -0,0 +1,53 @@
1
+ require 'payload'
2
+ require 'payload/arm/object'
3
+ require 'date'
4
+ require_relative '../../support/helpers'
5
+
6
+ RSpec.describe 'Invoice Integration Tests - V1' do
7
+ include_context 'test helpers'
8
+
9
+ let(:session) { Payload::Session.new(Payload.api_key, Payload.api_url, 1) }
10
+ let(:h) { V1Helpers.new(session) }
11
+
12
+ let(:proc_account) { h.create_processing_account }
13
+ let(:customer_account) { h.create_customer_account }
14
+ let(:invoice) { h.create_invoice(proc_account, customer_account) }
15
+
16
+ describe 'Invoice' do
17
+ it 'creates an invoice' do
18
+ inv = invoice
19
+ expect(inv.due_date).to eq(Date.today.strftime('%Y-%m-%d'))
20
+ expect(inv.status).to eq('unpaid')
21
+ end
22
+
23
+ it 'pays an invoice' do
24
+ inv = invoice
25
+ expect(inv.due_date).to eq(Date.today.strftime('%Y-%m-%d'))
26
+ expect(inv.status).to eq('unpaid')
27
+
28
+ amount = inv.amount_due
29
+
30
+ if inv.status != 'paid'
31
+ h.create_card_payment(
32
+ proc_account.id,
33
+ amount: amount,
34
+ description: 'Test Payment',
35
+ customer_id: customer_account.id,
36
+ invoice_id: inv.id
37
+ )
38
+ end
39
+
40
+ get_invoice = session.Invoice.get(inv.id)
41
+ expect(get_invoice.status).to eq('paid')
42
+ end
43
+
44
+ it 'deletes an invoice' do
45
+ inv = invoice
46
+ inv.delete
47
+
48
+ expect {
49
+ session.Invoice.get(inv.id)
50
+ }.to raise_error(Payload::NotFound)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,50 @@
1
+ require 'payload'
2
+ require 'payload/arm/object'
3
+ require_relative '../../support/helpers'
4
+
5
+ RSpec.describe 'Payment Link Integration Tests - V1' do
6
+ include_context 'test helpers'
7
+
8
+ let(:session) { Payload::Session.new(Payload.api_key, Payload.api_url, 1) }
9
+ let(:h) { V1Helpers.new(session) }
10
+
11
+ describe 'Payment Link' do
12
+
13
+ it 'creates a one-time payment link' do
14
+ proc_account = h.create_processing_account
15
+ payment_link = h.create_payment_link_one_time(proc_account)
16
+
17
+ expect(payment_link.processing_id).to eq(proc_account.id)
18
+ expect(payment_link.type).to eq('one_time')
19
+ end
20
+
21
+ it 'creates a reusable payment link' do
22
+ proc_account = h.create_processing_account
23
+ payment_link = h.create_payment_link_reusable(proc_account)
24
+
25
+ expect(payment_link.processing_id).to eq(proc_account.id)
26
+ expect(payment_link.type).to eq('reusable')
27
+ end
28
+
29
+ it 'deletes a reusable payment link' do
30
+ proc_account = h.create_processing_account
31
+ payment_link = h.create_payment_link_reusable(proc_account)
32
+ payment_link.delete
33
+
34
+ expect {
35
+ session.PaymentLink.get(payment_link.id)
36
+ }.to raise_error(Payload::NotFound)
37
+ end
38
+
39
+ it 'deletes a one-time payment link' do
40
+ proc_account = h.create_processing_account
41
+ payment_link = h.create_payment_link_one_time(proc_account)
42
+ payment_link.delete
43
+
44
+ expect {
45
+ session.PaymentLink.get(payment_link.id)
46
+ }.to raise_error(Payload::NotFound)
47
+ end
48
+ end
49
+ end
50
+