payload-api 0.0.0 → 0.2.2

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
2
  SHA256:
3
- metadata.gz: a3fb1c5560cf78f19c57bd89cdb1e13baf1ed62724aeaf79f8540063aef38ec1
4
- data.tar.gz: 118974f17c2e63757df0720945ef7c2bce8a8a306f4ae22dc88caf1745883d2e
3
+ metadata.gz: 38980b3bd2036f9866edb037fb8f818fdf7e898f135d5455a215b8bee17015c4
4
+ data.tar.gz: af087a2972eb1c1e364686dba0322b578b4d9d303fef51a12aa55d9ec0b64420
5
5
  SHA512:
6
- metadata.gz: b3ff208b9b111d64cbb18807da8600bc4bb7dcb92b68746f21079eab95a3caf51fa089352530023a1ff4d7dc53352d3a9db68d77efba25d6b842d079fb6a73d0
7
- data.tar.gz: eebbf9fa92b613fe279f3d322a8694f322e73954c7743483a222fd82dc8c0baa9b97010ccfc6c9e7ba4d5db33ab2c23ec866c82ae23c875d377ef64337d63d1e
6
+ metadata.gz: '068855eba39ba1fb7ee3f62fba3b156652a313952a4eda6e1bf2cbfe42d7a853a51ffae1bf95cf693d54e12fded3df126cca590d91a27509824b34ef9cffe4bd'
7
+ data.tar.gz: 0ce14cf0fbf7caa90907d709267b05af5838f664f8130b8c34cc3bbbdafb2233921723a7f625e6db298d8536588f86705223f94417067f088a7482d752d5a68b
data/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # Payload RubyGem
2
2
 
3
- A RubyGem for interfacing with the Payload API
3
+ A RubyGem for integrating [Payload](https://payload.co).
4
4
 
5
5
  ## Installation
6
6
 
7
7
  To install using [Bundler](https://bundler.io):
8
8
 
9
9
  ```ruby
10
- gem 'place-api', '~> 0.5.5'
10
+ gem 'payload-api', '~> 0.1.0'
11
11
  ```
12
12
 
13
13
  To install using gem:
@@ -16,9 +16,81 @@ To install using gem:
16
16
  gem install payload
17
17
  ```
18
18
 
19
+ ## Get Started
19
20
 
20
- ## Basic usage
21
- Coming Soon
21
+ Once you've installed the Payload Python library to your environment,
22
+ import the `payload` module to get started. **Note:** We recommend
23
+ using the shorthand name of `pl` when importing.
24
+
25
+ ```python
26
+ import payload as pl
27
+ ```
28
+
29
+ ### API Authentication
30
+
31
+ To authenticate with the Payload API, you'll need a live or test API key. API
32
+ keys are accessible from within the Payload dashboard.
33
+
34
+ ```python
35
+ import payload as pl
36
+ pl.api_key = 'secret_key_3bW9JMZtPVDOfFNzwRdfE'
37
+ ```
38
+
39
+ ### Creating an Object
40
+
41
+ Interfacing with the Payload API is done primarily through Payload Objects. Below is an example of
42
+ creating a customer using the `Payload::Customer` object.
43
+
44
+
45
+ ```ruby
46
+ # Create a Customer
47
+ customer = Payload::Customer.create(
48
+ email: 'matt.perez@example.com',
49
+ name: 'Matt Perez'
50
+ )
51
+ ```
52
+
53
+
54
+ ```ruby
55
+ # Create a Payment
56
+ payment = Payload::Payment.create(
57
+ amount: 100.0,
58
+ payment_method: Payload::Card(
59
+ card_number: '4242 4242 4242 4242'
60
+ )
61
+ )
62
+ ```
63
+
64
+ ### Accessing Object Attributes
65
+
66
+ Object attributes are accessible through both dot and bracket notation.
67
+
68
+ ```ruby
69
+ customer.name
70
+ customer['name']
71
+ ```
72
+
73
+ ### Updating an Object
74
+
75
+ Updating an object is a simple call to the `update` object method.
76
+
77
+ ```ruby
78
+ # Updating a customer's email
79
+ customer.update( email: 'matt.perez@newwork.com' )
80
+ ```
81
+
82
+ ### Selecting Objects
83
+
84
+ Objects can be selected using any of their attributes.
85
+
86
+ ```ruby
87
+ # Select a customer by email
88
+ customers = Payload::Customer.filter_by(
89
+ email: 'matt.perez@example.com'
90
+ )
91
+ ```
22
92
 
23
93
  ## Documentation
24
- Read the [docs](https://docs.payload.co/?ruby)
94
+
95
+ To get further information on Payload's RubyGem and API capabilities,
96
+ visit the unabridged [Payload Documentation](https://docs.payload.co/?ruby).
data/lib/payload.rb CHANGED
@@ -1,6 +1,16 @@
1
- require "place/version"
1
+ require "payload/version"
2
+ require "payload/objects"
2
3
 
3
4
  module Payload
5
+ @URL = "https://api.payload.co"
6
+ @api_url = @URL
7
+ @api_key = nil
8
+
4
9
  class << self
10
+ attr_accessor :api_key, :api_url
11
+ end
12
+
13
+ def self.create(objects)
14
+ return Payload::ARMRequest.new().create(objects)
5
15
  end
6
16
  end
@@ -0,0 +1,85 @@
1
+ require "payload/arm/request"
2
+
3
+ module Payload
4
+ class ARMObject
5
+ @poly = nil
6
+ @data = nil
7
+ @@cache = {}
8
+
9
+ class << self
10
+ attr_reader :spec, :poly, :data
11
+ end
12
+
13
+ def initialize(data)
14
+ self.set_data(data)
15
+ end
16
+
17
+ def self.new(data)
18
+ if data.key?('id') and @@cache.key?(data['id'])
19
+ @@cache[data['id']].set_data(data)
20
+ return @@cache[data['id']]
21
+ else
22
+ inst = super
23
+ if data.key?('id') and not data['id'].nil? and not data['id'].empty?
24
+ @@cache[data['id']] = inst
25
+ end
26
+
27
+ return inst
28
+ end
29
+ end
30
+
31
+ def data
32
+ @data
33
+ end
34
+
35
+ def set_data(data)
36
+ @data = data
37
+ end
38
+
39
+ def method_missing(name, *args)
40
+ attr = name.to_s
41
+ if @data.key?(attr)
42
+ return @data[attr]
43
+ else
44
+ super
45
+ end
46
+ end
47
+
48
+ def [](key)
49
+ return @data[key]
50
+ end
51
+
52
+ def self.select(*args, **data)
53
+ return Payload::ARMRequest.new(self).select(*args, **data)
54
+ end
55
+
56
+ def self.filter_by(*args, **data)
57
+ return Payload::ARMRequest.new(self).filter_by(*args, **data)
58
+ end
59
+
60
+ def self.create(*args, **data)
61
+ if args.length != 0
62
+ return Payload::ARMRequest.new(self).create(args[0])
63
+ else
64
+ return Payload::ARMRequest.new(self).create(data)
65
+ end
66
+ end
67
+
68
+ def self.get(id)
69
+ return Payload::ARMRequest.new(self).get(id)
70
+ end
71
+
72
+ def self.delete(objects)
73
+ return Payload::ARMRequest.new(self).delete(objects)
74
+ end
75
+
76
+ def update(**update)
77
+ return Payload::ARMRequest.new(self.class)._request('Put', id: self.id, json: update)
78
+ end
79
+
80
+ def delete()
81
+ return Payload::ARMRequest.new(self.class)._request('Delete', id: self.id)
82
+ end
83
+ end
84
+ end
85
+
@@ -0,0 +1,145 @@
1
+ require "payload/exceptions"
2
+ require "payload/utils"
3
+ require "net/http"
4
+ require "uri"
5
+ require "json"
6
+
7
+ module Payload
8
+ class ARMRequest
9
+ @cls = nil
10
+
11
+ def initialize(cls=nil)
12
+ @cls = cls
13
+ @filters = {}
14
+ end
15
+
16
+ def select(*args, **data)
17
+ if @cls.poly
18
+ data = data.merge(@cls.poly)
19
+ end
20
+
21
+ return self
22
+ end
23
+
24
+ def filter_by(*args, **data)
25
+ if @cls.poly
26
+ data = data.merge(@cls.poly)
27
+ end
28
+
29
+ @filters = @filters.merge(data)
30
+
31
+ return self
32
+ end
33
+
34
+ def all()
35
+ return self._request('Get')
36
+ end
37
+
38
+ def get(id)
39
+ if id.nil? || id.empty?
40
+ throw 'id cannot be empty'
41
+ end
42
+
43
+ return self._request('Get', id: id)
44
+ end
45
+
46
+ def update(**updates)
47
+ return self.filter_by(mode: 'query')
48
+ ._request('Put', json: updates)
49
+ end
50
+
51
+ def delete(objects)
52
+ deletes = objects.map {|o| o.id }.join('|')
53
+ return self.filter_by(mode: 'query', id: deletes)
54
+ ._request('Delete')
55
+ end
56
+
57
+ def create(data)
58
+ if data.is_a? Array
59
+ data = data.map do |obj|
60
+ if obj.kind_of?(ARMObject)
61
+ if @cls and not obj.instance_of?(@cls)
62
+ throw "All objects must be of the same type"
63
+ end
64
+
65
+ @cls = obj.class
66
+ obj = obj.data
67
+ end
68
+
69
+ if @cls.poly
70
+ obj = obj.merge(@cls.poly)
71
+ end
72
+
73
+ obj
74
+ end
75
+
76
+ data = { object: 'list', values: data }
77
+ else
78
+ if @cls.poly
79
+ data = data.merge(@cls.poly)
80
+ end
81
+ end
82
+
83
+ return self._request('Post', json: data)
84
+ end
85
+
86
+ def _request(method, id: nil, json: nil)
87
+ if @cls.spec.key?("endpoint")
88
+ endpoint = @cls.spec["endpoint"]
89
+ else
90
+ endpoint = "/"+@cls.spec["object"]+"s"
91
+ end
92
+
93
+ if id
94
+ endpoint = File.join(endpoint, id)
95
+ end
96
+
97
+ url = URI.join(Payload::api_url, endpoint)
98
+ url.query = URI.encode_www_form(@filters)
99
+
100
+ http = Net::HTTP.new(url.host, url.port)
101
+
102
+ if url.port == 443
103
+ http.use_ssl = true
104
+ end
105
+
106
+ request = Net::HTTP.const_get(method).new(url.request_uri)
107
+ request.basic_auth(Payload::api_key, '')
108
+
109
+ if json
110
+ request.body = json.to_json
111
+ request.add_field('Content-Type', 'application/json')
112
+ end
113
+
114
+ response = http.request(request)
115
+
116
+ begin
117
+ data = JSON.parse(response.body)
118
+ rescue JSON::ParserError
119
+ if response.code == '500'
120
+ raise Payload::InternalError.new
121
+ else
122
+ raise Place::UnknownResponse.new
123
+ end
124
+ end
125
+
126
+ if response.code == '200'
127
+ if data['object'] == 'list'
128
+ return data['values'].map {|obj| Payload::get_cls(obj).new(obj) }
129
+ else
130
+ return Payload::get_cls(data).new(data)
131
+ end
132
+ else
133
+ for error in Payload::subclasses(Payload::PayloadError)
134
+ if error.code != response.code or error.name.split('::')[-1] != data['error_type']
135
+ next
136
+ end
137
+
138
+ raise error.new(data['description'], data)
139
+ end
140
+
141
+ raise Payload::BadRequest.new(data['description'], data)
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,48 @@
1
+ module Payload
2
+ class PayloadError < StandardError
3
+ @code = nil
4
+ class << self
5
+ attr_reader :code
6
+ end
7
+
8
+ def initialize(msg, details = nil)
9
+ super(msg)
10
+ @details = details
11
+ end
12
+ end
13
+
14
+ class UnknownResponse < PayloadError
15
+ end
16
+
17
+ class BadRequest < PayloadError
18
+ @code='400'
19
+ end
20
+
21
+ class InvalidAttributes < PayloadError
22
+ @code='400'
23
+ end
24
+
25
+ class Unauthorized < PayloadError
26
+ @code='401'
27
+ end
28
+
29
+ class Forbidden < PayloadError
30
+ @code='403'
31
+ end
32
+
33
+ class NotFound < PayloadError
34
+ @code='404'
35
+ end
36
+
37
+ class TooManyRequests < PayloadError
38
+ @code='429'
39
+ end
40
+
41
+ class InternalServerError < PayloadError
42
+ @code='500'
43
+ end
44
+
45
+ class ServiceUnavailable < PayloadError
46
+ @code='503'
47
+ end
48
+ end
@@ -0,0 +1,85 @@
1
+ require "payload/arm/object"
2
+
3
+ module Payload
4
+ class Account < ARMObject
5
+ @spec = { 'object' => 'account' }
6
+ end
7
+
8
+ class Customer < ARMObject
9
+ @spec = { 'object' => 'customer' }
10
+ end
11
+
12
+ class ProcessingAccount < ARMObject
13
+ @spec = { 'object' => 'processing_account' }
14
+ end
15
+
16
+ class Org < ARMObject
17
+ @spec = { 'object' => 'org', 'endoint' => '/account/orgs' }
18
+ end
19
+
20
+ class Transaction < ARMObject
21
+ @spec = { 'object' => 'transaction' }
22
+ end
23
+
24
+ class Payment < ARMObject
25
+ @spec = { 'object' => 'transaction' }
26
+ @poly = { 'type' => 'payment' }
27
+ end
28
+
29
+ class Refund < ARMObject
30
+ @spec = { 'object' => 'transaction' }
31
+ @poly = { 'type' => 'refund' }
32
+ end
33
+
34
+ class Ledger < ARMObject
35
+ @spec = { 'object' => 'transaction_ledger' }
36
+ end
37
+
38
+ class PaymentMethod < ARMObject
39
+ @spec = { 'object' => 'payment_method' }
40
+ end
41
+
42
+ class Card < ARMObject
43
+ @spec = { 'object' => 'payment_method' }
44
+ @poly = { 'type' => 'card' }
45
+ end
46
+
47
+ class BankAccount < ARMObject
48
+ @spec = { 'object' => 'payment_method' }
49
+ @poly = { 'type' => 'bank_account' }
50
+ end
51
+
52
+ class BillingSchedule < ARMObject
53
+ @spec = { 'object' => 'billing_schedule' }
54
+ end
55
+
56
+ class BillingCharge < ARMObject
57
+ @spec = { 'object' => 'billing_charge' }
58
+ end
59
+
60
+ class Invoice < ARMObject
61
+ @spec = { 'object' => 'invoice' }
62
+ end
63
+
64
+ class LineItem < ARMObject
65
+ @spec = { 'object' => 'line_item' }
66
+ end
67
+
68
+ class ChargeItem < ARMObject
69
+ @spec = { 'object' => 'line_item' }
70
+ @poly = { 'type' => 'charge' }
71
+ end
72
+
73
+ class PaymentItem < ARMObject
74
+ @spec = { 'object' => 'line_item' }
75
+ @poly = { 'type' => 'payment' }
76
+ end
77
+
78
+ class PaymentActivation < ARMObject
79
+ @spec = { 'object' => 'payment_activation' }
80
+ end
81
+
82
+ class Webhook < ARMObject
83
+ @spec = { 'object' => 'webhook' }
84
+ end
85
+ end
@@ -0,0 +1,38 @@
1
+ module Payload
2
+
3
+ def self.subclasses(super_cls)
4
+ ObjectSpace.each_object(Class).select { |cls| cls < super_cls }
5
+ end
6
+
7
+ def self.get_cls(data)
8
+ match = nil
9
+ for cls in subclasses(Payload::ARMObject)
10
+ if cls.spec['object'] != data['object']
11
+ next
12
+ end
13
+
14
+ if not cls.poly and not match
15
+ match = cls
16
+
17
+ elsif cls.poly
18
+
19
+ invalid = false
20
+ cls.poly.each do |key, value|
21
+ if data[key] != value
22
+ invalid = true
23
+ end
24
+ end
25
+
26
+ if invalid
27
+ next
28
+ end
29
+
30
+ match = cls
31
+ break
32
+ end
33
+ end
34
+
35
+ match
36
+ end
37
+
38
+ end
@@ -1,3 +1,3 @@
1
1
  module Payload
2
- VERSION = '0.0.0'
2
+ VERSION = '0.2.2'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: payload-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Payload
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-28 00:00:00.000000000 Z
11
+ date: 2021-08-14 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A simple library to interface with the Payload API. See https://docs.payload.co
14
14
  for details.
@@ -20,6 +20,11 @@ files:
20
20
  - LICENSE
21
21
  - README.md
22
22
  - lib/payload.rb
23
+ - lib/payload/arm/object.rb
24
+ - lib/payload/arm/request.rb
25
+ - lib/payload/exceptions.rb
26
+ - lib/payload/objects.rb
27
+ - lib/payload/utils.rb
23
28
  - lib/payload/version.rb
24
29
  - payload.gemspec
25
30
  homepage: https://docs.payload.co
@@ -41,8 +46,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
41
46
  - !ruby/object:Gem::Version
42
47
  version: '0'
43
48
  requirements: []
44
- rubyforge_project:
45
- rubygems_version: 2.7.7
49
+ rubygems_version: 3.2.5
46
50
  signing_key:
47
51
  specification_version: 4
48
52
  summary: Payload ruby library