paypal-sdk-subscriptions 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bf3c2ae219ecfbb92ab65651dc8872ff3910078ea184d0cbceb4fe2036ab5cc6
4
+ data.tar.gz: 5ca7bbaaf031ae947f5e9be0dcbf262cae4e94f3b6cdb17fe12793dc67fdcbd8
5
+ SHA512:
6
+ metadata.gz: a599da2bbdd4a8755c93f2c112e30abb3db51b065828851e8f1dca8ccfaf3c971df609475ba5780abd1fd08a997f2dcd14cf49b64fbc7f9d35c6dbf3d2794395
7
+ data.tar.gz: 39cff813fad29d860455080b92ac9e00e7c63705ef72ebcc560a4013a07cabd51ca9c7ca3f88e6fde0bd58d14bc7954f4ebf31f697b7d49a775b4f92fb7117f3
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ Gemfile.lock
2
+ /.bundle/
3
+ /.yardoc
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.5.1
7
+ before_install: gem install bundler -v 2.0.1
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in paypal-sdk-subscriptions.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Piers Chambers
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # PayPal REST SDK for Subscriptions Management
2
+
3
+ [![Version ][rubygems_badge]][rubygems]
4
+ [![Travis CI ][travis_badge]][travis]
5
+
6
+ Missing PayPal REST SDK for [Subscriptions Management][subscriptions_full_integration] [released April 2019][release_notes].
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'paypal-sdk-subscriptions'
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ ## Configuration
21
+
22
+ Create a configuration file(`config/paypal.yml`):
23
+
24
+ ```yaml
25
+ development: &default
26
+ mode: sandbox
27
+ client_id: <%= ENV.fetch('client_id') %>
28
+ client_secret: <%= ENV.fetch('client_secret') %>
29
+ test:
30
+ <<: *default
31
+ production:
32
+ mode: live
33
+ client_id: CLIENT_ID
34
+ client_secret: CLIENT_SECRET
35
+ ```
36
+
37
+ Load Configurations from specified file:
38
+
39
+ ```ruby
40
+ PayPal::SDK::Core::Config.load('spec/config/paypal.yml', ENV['RACK_ENV'] || 'development')
41
+ ```
42
+
43
+ Without configuration file:
44
+
45
+ ```ruby
46
+ PayPal::SDK.configure(
47
+ :mode => "sandbox", # "sandbox" or "live"
48
+ :client_id => ENV.fetch('client_id'),
49
+ :client_secret => ENV.fetch('client_secret'),
50
+ :ssl_options => { } )
51
+ ```
52
+
53
+ Logger configuration:
54
+
55
+ ```ruby
56
+ PayPal::SDK.logger = Logger.new(STDERR)
57
+
58
+ # change log level to INFO
59
+ PayPal::SDK.logger.level = Logger::INFO
60
+ ```
61
+ **NOTE**: At `DEBUG` level, all requests/responses are logged except when `mode` is set to `live`. In order to disable request/response printing, set the log level to `INFO` or less verbose ones.
62
+
63
+ ## Development
64
+
65
+ The test suite runs transactions against the PayPal sandbox, creating products and plans that it cannot delete. Initial tests may fail until at least one product and plan has been created.
66
+
67
+ To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
68
+
69
+ ## Contributing
70
+
71
+ Bug reports and pull requests are welcome on GitHub at https://github.com/varyonic]/paypal-sdk-subscriptions.
72
+
73
+ ## License
74
+
75
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
76
+
77
+ [rubygems_badge]: http://img.shields.io/gem/v/paypal-subscriptions-sdk-ruby.svg
78
+ [rubygems]: https://rubygems.org/gems/paypal-subscriptions-sdk-ruby
79
+ [travis_badge]: http://img.shields.io/travis/varyonic/paypal-subscriptions-sdk-ruby/master.svg
80
+ [travis]: https://travis-ci.org/varyonic/paypal-subscriptions-sdk-ruby
81
+
82
+ [release_notes]: https://developer.paypal.com/docs/release-notes/release-notes-2019/#april
83
+ [subscriptions_full_integration]: https://developer.paypal.com/docs/subscriptions/full-integration/subscription-management/
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "paypal/sdk/subscriptions"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/config/paypal.yml ADDED
@@ -0,0 +1,13 @@
1
+ test: &default
2
+ mode: sandbox
3
+ client_id: <%= ENV.fetch('client_id') %>
4
+ client_secret: <%= ENV.fetch('client_secret') %>
5
+
6
+ development:
7
+ <<: *default
8
+
9
+ production:
10
+ mode: live
11
+ client_id: CLIENT_ID
12
+ client_secret: CLIENT_SECRET
13
+ # rest_endpoint: "https://api.paypal.com"
@@ -0,0 +1,20 @@
1
+ require 'paypal-sdk-core'
2
+
3
+ module PayPal
4
+ module SDK
5
+ module Subscriptions
6
+ class Error < StandardError; end
7
+
8
+ autoload :VERSION, "paypal-sdk/subscriptions/version"
9
+ autoload :Base, "paypal-sdk/subscriptions/data_types"
10
+ autoload :ErrorHash, "paypal-sdk/subscriptions/error_hash"
11
+ autoload :Link, "paypal-sdk/subscriptions/link"
12
+ autoload :RequestBase, "paypal-sdk/subscriptions/request_base"
13
+ autoload :RequestDataType, "paypal-sdk/subscriptions/request_data_type"
14
+
15
+ autoload :Plan, "paypal-sdk/subscriptions/plan"
16
+ autoload :Product, "paypal-sdk/subscriptions/product"
17
+ autoload :Subscription, "paypal-sdk/subscriptions/subscription"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ module PayPal::SDK::Subscriptions
2
+
3
+ class Base < PayPal::SDK::Core::API::DataTypes::Base
4
+ class Number < Float
5
+ end
6
+ end
7
+
8
+ class EnumType < PayPal::SDK::Core::API::DataTypes::Enum
9
+ end
10
+
11
+ class Money < Base
12
+ object_of :currency_code, String
13
+ object_of :value, String
14
+ end
15
+ end
@@ -0,0 +1,39 @@
1
+ module PayPal
2
+ module SDK
3
+ module Subscriptions
4
+ class ErrorHash < Core::Util::OrderedHash
5
+ def self.convert(hash)
6
+ error_hash = new
7
+ hash.each{|key, value|
8
+ error_hash[key] = value
9
+ }
10
+ error_hash
11
+ end
12
+
13
+ def []=(key, value)
14
+ value =
15
+ if value.is_a? Hash
16
+ ErrorHash.convert(value)
17
+ elsif value.is_a? Array and value[0].is_a? Hash
18
+ value.map{|array_value| ErrorHash.convert(array_value) }
19
+ else
20
+ value
21
+ end
22
+ super(key, value)
23
+ end
24
+
25
+ def [](name)
26
+ super(name.to_s) || super(name.to_sym)
27
+ end
28
+
29
+ def method_missing(name, *args)
30
+ if keys.include?(name) or keys.include?(name.to_s)
31
+ self[name]
32
+ else
33
+ super
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,14 @@
1
+ module PayPal::SDK::Subscriptions
2
+ # https://developer.paypal.com/docs/api/reference/api-responses/#hateoas-links
3
+ # https://developer.paypal.com/docs/api/subscriptions/v1/#definition-link_description
4
+ class Link < RequestBase
5
+ object_of :href, String
6
+ object_of :rel, String
7
+ object_of :method, String
8
+
9
+ def call
10
+ response = api.api_call(method: link.method, uri: URI.parse(link.href), header: {})
11
+ response
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,108 @@
1
+ module PayPal::SDK::Subscriptions
2
+ # v1/billing/plans
3
+ class Plan < RequestBase
4
+
5
+ class BillingCycle < Base
6
+ class Frequency < Base
7
+ object_of :interval_unit, String
8
+ object_of :interval_count, Integer
9
+ end
10
+
11
+ class PricingScheme < Base
12
+ object_of :version, Integer
13
+ object_of :fixed_price, Money
14
+ object_of :create_time, DateTime
15
+ end
16
+
17
+ object_of :frequency, Frequency
18
+ object_of :tenure_type, String
19
+ object_of :sequence, Integer
20
+ object_of :total_cycles, Integer
21
+ object_of :pricing_scheme, PricingScheme
22
+ end
23
+
24
+ # https://developer.paypal.com/docs/api/subscriptions/v1/#definition-payment_preferences
25
+ class PaymentPreferences < Base
26
+ object_of :service_type, String
27
+ object_of :auto_bill_outstanding, Boolean # default: true
28
+ object_of :setup_fee, Money
29
+ object_of :setup_fee_failure_action, String # CANCEL(default)|CONTINUE
30
+ object_of :payment_failure_threshold, Integer # default: 0
31
+ end
32
+
33
+ class Taxes < Base
34
+ object_of :percentage, Number
35
+ object_of :inclusive, Boolean
36
+ end
37
+
38
+ # https://developer.paypal.com/docs/api/subscriptions/v1/#plans_patch
39
+ # patch [Hash] { op: 'replace', path: , value: }
40
+ # path = [description|payment_preferences.auto_bill_outstanding|taxes.percentage|payment_preferences.payment_failure_threshold]
41
+ def update(patch)
42
+ super
43
+ end
44
+
45
+ def update_pricing(*schemes)
46
+ payload = { pricing_schemes: schemes.map(&:to_hash) }
47
+ commit("#{path(id)}/update-pricing-schemes", payload)
48
+ end
49
+ raise_on_api_error :update_pricing
50
+
51
+ def activate
52
+ commit("#{path(id)}/activate")
53
+ end
54
+ raise_on_api_error :activate
55
+
56
+ def deactivate
57
+ commit("#{path(id)}/deactivate")
58
+ end
59
+ raise_on_api_error :deactivate
60
+
61
+ raise_on_api_error :create, :update
62
+
63
+ class Page < RequestBase
64
+ object_of :total_items, Integer
65
+ object_of :total_pages, Integer
66
+ array_of :plans, Plan
67
+ array_of :links, Link # self, next, last
68
+
69
+ def next
70
+ link = links.detect { |l| l.rel == 'next' }
71
+ if link
72
+ uri = URI.parse(link.href)
73
+ response = api.api_call(method: :get, uri: uri, header: {})
74
+ self.class.new(response)
75
+ end
76
+ end
77
+ end
78
+
79
+ class << self
80
+ def path(resource_id = nil)
81
+ "v1/billing/plans/#{resource_id}"
82
+ end
83
+
84
+ # options include 'page', 'page_size', and 'total_required'
85
+ def all(options = {})
86
+ Page.new(api.get(path, options))
87
+ end
88
+ end
89
+
90
+ def reload
91
+ merge! api.get(self.class.path id)
92
+ success?
93
+ end
94
+
95
+ object_of :product_id, String
96
+ object_of :id, String
97
+ object_of :name, String
98
+ object_of :description, String
99
+ object_of :status, String # CREATED|ACTIVE|INACTIVE
100
+ array_of :billing_cycles, BillingCycle
101
+ object_of :payment_preferences, PaymentPreferences
102
+ object_of :quantity_supported, Boolean
103
+ object_of :taxes, Taxes
104
+ object_of :create_time, String
105
+ object_of :update_time, String
106
+ array_of :links, Link
107
+ end
108
+ end
@@ -0,0 +1,48 @@
1
+ module PayPal::SDK::Subscriptions
2
+ # https://developer.paypal.com/docs/api/catalog-products/v1/
3
+ class Product < RequestBase
4
+ object_of :id, String # 6-50 chars. Default: system generated, prefixed with PROD-
5
+ object_of :name, String
6
+ object_of :description, String
7
+ object_of :type, String # PHYSICAL|DIGITAL|SERVICE
8
+ object_of :category, String
9
+ object_of :image_url, String
10
+ object_of :home_url, String
11
+ object_of :create_time, String
12
+ object_of :update_time, String
13
+ array_of :links, Link
14
+
15
+ # patch [Hash] { op: 'replace', path: , value: }
16
+ # path = [/description|/category|/image_url|/home_url]
17
+ def update(patch)
18
+ super
19
+ end
20
+
21
+ class Page < RequestBase
22
+ object_of :total_items, Integer
23
+ object_of :total_pages, Integer
24
+ array_of :products, Product
25
+ array_of :links, Link # self, next, last
26
+
27
+ def next
28
+ link = links.detect { |l| l.rel == 'next' }
29
+ if link
30
+ uri = URI.parse(link.href)
31
+ response = api.api_call(method: :get, uri: uri, header: {})
32
+ self.class.new(response)
33
+ end
34
+ end
35
+ end
36
+
37
+ class << self
38
+ def path(resource_id = nil)
39
+ "v1/catalogs/products/#{resource_id}"
40
+ end
41
+
42
+ # options include 'page', 'page_size', and 'total_required'
43
+ def all(options = {})
44
+ Page.new(api.get(path, options))
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,100 @@
1
+ require 'securerandom'
2
+
3
+ module PayPal::SDK::Core::Exceptions
4
+ # 422 Unprocessable Entity
5
+ class ResourceInvalid < ClientError # :nodoc:
6
+ end
7
+ end
8
+
9
+ module PayPal::SDK::Subscriptions
10
+ include PayPal::SDK::Core::Exceptions
11
+
12
+ # API error: returned as 200 + "error" key in response.
13
+ class UnsuccessfulApiCall < RuntimeError
14
+ attr_reader :api_error
15
+
16
+ def initialize(api_error)
17
+ super(api_error['message'])
18
+ @api_error = api_error
19
+ end
20
+ end
21
+
22
+ class RequestAPIBase < PayPal::SDK::Core::API::DataTypes::Base
23
+ include RequestDataType
24
+
25
+ attr_accessor :error
26
+ attr_writer :header, :request_id
27
+
28
+ def header
29
+ @header ||= {}
30
+ end
31
+
32
+ def request_id
33
+ @request_id ||= SecureRandom.uuid
34
+ end
35
+
36
+ def http_header
37
+ { "PayPal-Request-Id" => request_id.to_s }.merge(header)
38
+ end
39
+
40
+ def success?
41
+ @error.nil?
42
+ end
43
+
44
+ def merge!(values)
45
+ @error = nil
46
+ super
47
+ end
48
+
49
+ def raise_error!
50
+ raise UnsuccessfulApiCall, error if error
51
+ end
52
+
53
+ def self.raise_on_api_error(*methods)
54
+ methods.each do |symbol|
55
+ define_method("#{symbol}!") {|*arg|
56
+ raise_error! unless send(symbol, *arg)
57
+ }
58
+ end
59
+ end
60
+ end
61
+
62
+ class Patch < Base
63
+ object_of :op, String
64
+ object_of :path, String
65
+ object_of :value, Object
66
+ object_of :from, String
67
+ end
68
+
69
+ class RequestBase < RequestAPIBase
70
+ def path(id = nil)
71
+ self.class.path(id)
72
+ end
73
+
74
+ def commit(path, data = {}, method = :post)
75
+ merge! api.send(method, path, data, http_header)
76
+ success?
77
+ end
78
+
79
+ def self.create!(attrs)
80
+ new(attrs).tap(&:create!)
81
+ end
82
+
83
+ def create
84
+ commit(path, to_hash)
85
+ end
86
+ raise_on_api_error :create
87
+
88
+ def self.find(resource_id)
89
+ raise ArgumentError.new("id required") if resource_id.to_s.strip.empty?
90
+ new api.get(path resource_id)
91
+ end
92
+
93
+ # patch [Hash] { op: 'replace', path: , value: }
94
+ def update(patch)
95
+ patch = Patch.new(patch) unless patch.is_a? Patch
96
+ commit(path(id), [patch.to_hash], :patch)
97
+ end
98
+ raise_on_api_error :update
99
+ end
100
+ end
@@ -0,0 +1,71 @@
1
+ module PayPal
2
+ module SDK
3
+ module Subscriptions
4
+ module GetAPI
5
+ # Get API object
6
+ # === Example
7
+ # Payment.api
8
+ # payment.api
9
+ def api
10
+ @api || parent_api
11
+ end
12
+
13
+ # Parent API object
14
+ def parent_api
15
+ superclass.respond_to?(:api) ? superclass.api : RequestDataType.api
16
+ end
17
+ end
18
+
19
+ class API < Core::API::REST
20
+ def initialize(environment = nil, options = {})
21
+ super("", environment, options)
22
+ end
23
+
24
+ class << self
25
+ def user_agent
26
+ @user_agent ||= "PayPalSDK/PayPal-Subscriptions-Ruby-SDK #{PayPal::SDK::Subscriptions::VERSION} (#{sdk_library_details})"
27
+ end
28
+ end
29
+ end
30
+
31
+ module RequestDataType
32
+ # Get a local API object or Class level API object
33
+ def api
34
+ @api || self.class.api
35
+ end
36
+
37
+ # Convert Hash object to ErrorHash object
38
+ def error=(hash)
39
+ @error =
40
+ if hash.is_a? Hash
41
+ ErrorHash.convert(hash)
42
+ else
43
+ hash
44
+ end
45
+ end
46
+
47
+ class << self
48
+ # Global API object
49
+ # === Example
50
+ # RequestDataType.api
51
+ def api
52
+ @api ||= API.new
53
+ end
54
+
55
+ # Configure depended module, when RequestDataType is include.
56
+ # === Example
57
+ # class Payment < DataTypes
58
+ # include RequestDataType
59
+ # end
60
+ # Payment.api
61
+ # payment.api
62
+ def included(klass)
63
+ klass.class_eval do
64
+ extend GetAPI
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,125 @@
1
+ module PayPal::SDK::Subscriptions
2
+ # https://developer.paypal.com/docs/api/subscriptions/v1/#subscriptions
3
+ class Subscription < RequestBase
4
+
5
+ def self.path(resource_id = nil)
6
+ "v1/billing/subscriptions/#{resource_id}"
7
+ end
8
+
9
+ class Subscriber < Base
10
+ class SubscriberName < Base
11
+ object_of :given_name, String
12
+ object_of :surname, String
13
+ end
14
+
15
+ class ShippingAddress < Base
16
+ class BaseAddress < Base
17
+ object_of :address_line_1, String
18
+ object_of :address_line_2, String
19
+ object_of :admin_area_2, String
20
+ object_of :admin_area_1, String
21
+ object_of :postal_code, String
22
+ object_of :country_code, String
23
+ end
24
+
25
+ class FullName < Base
26
+ object_of :full_name, String
27
+ end
28
+
29
+ object_of :name, FullName
30
+ object_of :address, BaseAddress
31
+ end
32
+
33
+ object_of :name, SubscriberName
34
+ object_of :email_address, String
35
+ object_of :shipping_address, ShippingAddress
36
+ end
37
+
38
+ # https://developer.paypal.com/docs/api/subscriptions/v1/#definition-application_context
39
+ class ApplicationContext < Base
40
+ class PaymentMethod < Base
41
+ object_of :payer_selected, String
42
+ object_of :payee_preferred, String
43
+ end
44
+
45
+ object_of :id, String
46
+ object_of :brand_name, String
47
+ object_of :locale, String
48
+ object_of :shipping_preference, String # GET_FROM_FILE(default)|NO_SHIPPING|SET_PROVIDED_ADDRESS
49
+ object_of :user_action, String
50
+ object_of :payment_method, PaymentMethod
51
+ object_of :return_url, String
52
+ object_of :cancel_url, String
53
+ end
54
+
55
+ object_of :plan_id, String
56
+ object_of :id, String
57
+ object_of :start_time, DateTime # default: Time.now
58
+ object_of :status, String # APPROVAL_PENDING|APPROVED|ACTIVE|SUSPENDED|CANCELLED|EXPIRED
59
+ object_of :status_update_time, DateTime
60
+ object_of :quantity, Integer
61
+ object_of :shipping_amount, Money
62
+ object_of :subscriber, Subscriber
63
+ object_of :auto_renewal, Boolean
64
+ object_of :application_context, ApplicationContext
65
+ object_of :create_time, DateTime
66
+ array_of :links, Link
67
+
68
+ def activate
69
+ commit("#{path(id)}/activate")
70
+ end
71
+ raise_on_api_error :activate
72
+
73
+ def cancel
74
+ commit("#{path(id)}/cancel")
75
+ end
76
+ raise_on_api_error :cancel
77
+
78
+ # @return [Hash] Transaction info
79
+ def capture(note, amount)
80
+ payload = { amount: amount, note: note, capture_type: 'OUTSTANDING_BALANCE' }
81
+ api.post("#{path(id)}/capture", payload, http_header)
82
+ end
83
+ raise_on_api_error :capture
84
+
85
+ def suspend(note)
86
+ commit("#{path(id)}/suspend", reason: note)
87
+ end
88
+ raise_on_api_error :suspend
89
+
90
+ class Transaction < RequestBase
91
+ class TransactionStatus < EnumType
92
+ self.options = %w(COMPLETED DECLINED PARTIALLY_REFUNDED PENDING REFUNDED)
93
+ end
94
+ object_of :status, TransactionStatus
95
+ object_of :id, String
96
+ object_of :amount_with_breakdown, Hash
97
+ object_of :payer_name, Hash
98
+ object_of :payer_email, String
99
+ object_of :time, DateTime
100
+
101
+ class Page < RequestBase
102
+ array_of :transactions, Transaction
103
+ object_of :total_items, Integer
104
+ object_of :total_pages, Integer
105
+ array_of :links, Link # self, next, last
106
+ end
107
+ end
108
+
109
+ # option :start_time [Time|String] (required)
110
+ # option :end_time [Time|String] (default: now)
111
+ def transactions(options = {})
112
+ options[:end_time] ||= Time.now
113
+
114
+ start_time = DateTime.parse(options[:start_time].to_s).strftime('%Y-%m-%dT%H:%M:%S.%L%:z')
115
+ end_time = DateTime.parse(options[:end_time].to_s).strftime('%Y-%m-%dT%H:%M:%S.%L%:z')
116
+
117
+ response = api.get("#{path(id)}/transactions", start_time: start_time, end_time: end_time)
118
+
119
+ page = Transaction::Page.new(response)
120
+ page.merge!(response)
121
+ page.raise_error!
122
+ page
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,7 @@
1
+ module PayPal
2
+ module SDK
3
+ module Subscriptions
4
+ VERSION = "0.1.0"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,30 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "paypal-sdk/subscriptions/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "paypal-sdk-subscriptions"
8
+ spec.version = PayPal::SDK::Subscriptions::VERSION
9
+ spec.authors = ["Piers Chambers"]
10
+ spec.email = ["piers@varyonic.com"]
11
+
12
+ spec.summary = %q{Missing PayPal REST SDK for Subscriptions Management.}
13
+ spec.homepage = "https://github.com/varyonic/paypal-subscriptions-sdk-ruby"
14
+ spec.license = "MIT"
15
+
16
+ # Specify which files should be added to the gem when it is released.
17
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
18
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
19
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec)/}) }
20
+ end
21
+ spec.bindir = "exe"
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = ["lib"]
24
+
25
+ spec.add_development_dependency('paypal-sdk-core')
26
+
27
+ spec.add_development_dependency "bundler", "~> 2.0"
28
+ spec.add_development_dependency "rake", "~> 10.0"
29
+ spec.add_development_dependency "rspec", "~> 3.0"
30
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: paypal-sdk-subscriptions
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Piers Chambers
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-07-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: paypal-sdk-core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ description:
70
+ email:
71
+ - piers@varyonic.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".rspec"
78
+ - ".travis.yml"
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - bin/console
84
+ - bin/setup
85
+ - config/paypal.yml
86
+ - lib/paypal-sdk/subscriptions.rb
87
+ - lib/paypal-sdk/subscriptions/data_types.rb
88
+ - lib/paypal-sdk/subscriptions/error_hash.rb
89
+ - lib/paypal-sdk/subscriptions/link.rb
90
+ - lib/paypal-sdk/subscriptions/plan.rb
91
+ - lib/paypal-sdk/subscriptions/product.rb
92
+ - lib/paypal-sdk/subscriptions/request_base.rb
93
+ - lib/paypal-sdk/subscriptions/request_data_type.rb
94
+ - lib/paypal-sdk/subscriptions/subscription.rb
95
+ - lib/paypal-sdk/subscriptions/version.rb
96
+ - paypal-sdk-subscriptions.gemspec
97
+ homepage: https://github.com/varyonic/paypal-subscriptions-sdk-ruby
98
+ licenses:
99
+ - MIT
100
+ metadata: {}
101
+ post_install_message:
102
+ rdoc_options: []
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ requirements: []
116
+ rubygems_version: 3.0.3
117
+ signing_key:
118
+ specification_version: 4
119
+ summary: Missing PayPal REST SDK for Subscriptions Management.
120
+ test_files: []