Class: AbacatePay::Clients::SubscriptionClient

Inherits:
Client
  • Object
show all
Defined in:
lib/abacate_pay/clients/subscription_client.rb

Overview

Client for recurring subscriptions in the AbacatePay API.

See Enums::Products::Cycles for the supported billing cycles.

Constant Summary collapse

URI =
"subscriptions"

Constants inherited from Client

Client::RETRIABLE_EXCEPTIONS, Client::RETRIABLE_METHODS, Client::RETRIABLE_STATUSES

Instance Method Summary collapse

Methods inherited from Client

#auto_paging_each, #each_page

Constructor Details

#initialize(client = nil) ⇒ SubscriptionClient

Returns a new instance of SubscriptionClient.



11
12
13
# File 'lib/abacate_pay/clients/subscription_client.rb', line 11

def initialize(client = nil)
  super(URI, client)
end

Instance Method Details

#cancel(id) ⇒ Resources::Subscriptions

Cancels an active subscription immediately. Pending future instalments are cancelled along with it.

Parameters:

  • id (String)

    The subscription ID (subs_...)

Returns:



44
45
46
47
# File 'lib/abacate_pay/clients/subscription_client.rb', line 44

def cancel(id)
  response = request("POST", "cancel", json: { id: id })
  Resources::Subscriptions.new(response)
end

#change_plan(id, product_id:, quantity: 1) ⇒ Hash

Changes the main product of an active subscription. The new price takes effect on the next billing cycle, the current cycle is untouched.

Parameters:

  • id (String)

    The subscription ID (subs_...)

  • product_id (String)

    The new product ID (prod_...), which must have a cycle

  • quantity (Integer) (defaults to: 1)

    Quantity of the product, minimum 1

Returns:

  • (Hash)

    The pending update object (status: "PENDING")

Raises:

  • (ArgumentError)

    if quantity is below 1



57
58
59
60
61
# File 'lib/abacate_pay/clients/subscription_client.rb', line 57

def change_plan(id, product_id:, quantity: 1)
  raise ArgumentError, "quantity must be at least 1, got #{quantity.inspect}" if quantity.to_i < 1

  request("POST", "change-plan", json: { id: id, productId: product_id, quantity: quantity.to_i })
end

#create(data) ⇒ Resources::Subscriptions

Parameters:

Returns:



24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/abacate_pay/clients/subscription_client.rb', line 24

def create(data)
  request_data = {
    methods: data.methods,
    externalId: data.external_id,
    customerId: data.customer&.id,
    # The API expects the product id here, the same shape checkouts use.
    # Sending externalId fails with
    # "Expected property 'items.0.id' to be string".
    items: data.products&.map { |product| { id: product.external_id, quantity: product.quantity } }
  }

  response = request("POST", "create", json: request_data)
  Resources::Subscriptions.new(response)
end

#list(**params) ⇒ Array<Resources::Subscriptions>

Parameters:

  • params (Hash)

    Optional pagination params (after, before, limit)

Returns:



17
18
19
20
# File 'lib/abacate_pay/clients/subscription_client.rb', line 17

def list(**params)
  response = request("GET", "list", params: params.empty? ? nil : params)
  build_list(response, Resources::Subscriptions)
end

#record_usage(id, product_id:, units:, action: "add") ⇒ Hash

Records usage of a pay-as-you-go product on an active subscription. The amount is added to the next pending instalment of the cycle.

Parameters:

  • id (String)

    The subscription ID (subs_...)

  • product_id (String)

    The usage product ID (prod_...), which must NOT have a cycle

  • units (Integer)

    Number of units, minimum 1

  • action (String) (defaults to: "add")

    "add" to add units, "subtract" to reverse units already recorded in the same cycle

Returns:

  • (Hash)

    The recorded usage

Raises:

  • (ArgumentError)

    if units is below 1 or action is not add/subtract



73
74
75
76
77
78
79
80
81
82
# File 'lib/abacate_pay/clients/subscription_client.rb', line 73

def record_usage(id, product_id:, units:, action: "add")
  raise ArgumentError, "units must be at least 1, got #{units.inspect}" if units.to_i < 1

  unless %w[add subtract].include?(action.to_s)
    raise ArgumentError, "action must be \"add\" or \"subtract\", got #{action.inspect}"
  end

  request("POST", "record-usage",
          json: { id: id, productId: product_id, units: units.to_i, action: action.to_s })
end