Class: AdvancedBilling::SubscriptionsController

Inherits:
BaseController show all
Defined in:
lib/advanced_billing/controllers/subscriptions_controller.rb

Overview

SubscriptionsController

Constant Summary

Constants inherited from BaseController

BaseController::GLOBAL_ERRORS

Instance Attribute Summary

Attributes inherited from BaseController

#config, #http_call_back

Instance Method Summary collapse

Methods inherited from BaseController

#initialize, #new_parameter, #new_request_builder, #new_response_handler, user_agent, user_agent_parameters

Constructor Details

This class inherits a constructor from AdvancedBilling::BaseController

Instance Method Details

#activate_subscription(subscription_id, body: nil) ⇒ SubscriptionResponse

Activates awaiting signup and trialing subscriptions. This feature is only available on the Relationship Invoicing architecture. Subscriptions in a group cannot be activated immediately. The revert_on_failure parameter controls the behavior upon activation failure.

  • If set to true and something goes wrong i.e. payment fails, the subscription's state does not change. The subscription’s billing period also remains the same.
  • If set to false and something goes wrong i.e. payment fails, the activation continues and enters an end of life state. For trialing subscriptions, that is either trial ended (if the trial is no obligation), past due (if the trial has an obligation), or canceled (if the site has no dunning strategy, or has a strategy that says to cancel immediately). For awaiting signup subscriptions, that is always canceled. The default activation failure behavior can be configured per activation attempt, or you can set a default value under Config > Settings > Subscription Activation Settings.

Activation Scenarios

Activate Awaiting Signup subscription

  • Given you have a product without trial
  • Given you have a site without dunning strategy
  flowchart LR
    AS[Awaiting Signup] --> A{Activate}
    A -->|Success| Active
    A -->|Failure| ROF{revert_on_failure}
    ROF -->|true| AS
    ROF -->|false| Canceled
  • Given you have a product with trial
  • Given you have a site with dunning strategy
  flowchart LR
    AS[Awaiting Signup] --> A{Activate}
    A -->|Success| Trialing
    A -->|Failure| ROF{revert_on_failure}
    ROF -->|true| AS
    ROF -->|false| PD[Past Due]

Activate Trialing subscription

For more information about the behavior of trialing subscriptions, see [Trialing Subscriptions](https://maxio.zendesk.com/hc/en-us/articles/24252155721869- Trialing-Subscriptions). When the revert_on_failure parameter is set to true, the subscription's state remains Trialing; the invoice from activation is voided, and any prepayments and credits applied to the invoice are returned to the subscription. the subscription. description here

Parameters:

  • subscription_id (Integer)

    Required parameter: The Chargify id of

  • body (ActivateSubscriptionRequest) (defaults to: nil)

    Optional parameter: TODO: type

Returns:



760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
# File 'lib/advanced_billing/controllers/subscriptions_controller.rb', line 760

def activate_subscription(subscription_id,
                          body: nil)
  @api_call
    .request(new_request_builder(HttpMethodEnum::PUT,
                                 '/subscriptions/{subscription_id}/activate.json',
                                 Server::PRODUCTION)
               .template_param(new_parameter(subscription_id, key: 'subscription_id')
                                .is_required(true)
                                .should_encode(true))
               .header_param(new_parameter('application/json', key: 'Content-Type'))
               .body_param(new_parameter(body))
               .header_param(new_parameter('application/json', key: 'accept'))
               .body_serializer(proc do |param| param.to_json unless param.nil? end)
               .auth(Single.new('BasicAuth')))
    .response(new_response_handler
                .deserializer(APIHelper.method(:custom_type_deserializer))
                .deserialize_into(SubscriptionResponse.method(:from_hash))
                .local_error_template('400',
                                      'HTTP Response Not OK. Status code: {$statusCode}.'\
                                       ' Response: \'{$response.body}\'.',
                                      ErrorArrayMapResponseException))
    .execute
end

#apply_coupons_to_subscription(subscription_id, code: nil, body: nil) ⇒ SubscriptionResponse

Applies one or more coupon codes to an existing subscription. An existing subscription can accommodate multiple discounts/coupon codes. This is only applicable if each coupon is stackable. For more information on stackable coupons, we recommend reviewing our [coupon documentation.](https://maxio.zendesk.com/hc/en-us/articles/24261259337101 -Coupons-and-Subscriptions#stackability-rules)

Query Parameters vs Request Body Parameters

Passing in a coupon code as a query parameter will add the code to the subscription, completely replacing all existing coupon codes on the subscription. For this reason, using this query parameter on this endpoint has been deprecated in favor of using the request body parameters as described below. When passing in request body parameters, the list of coupon codes will simply be added to any existing list of codes on the subscription. the subscription. be applied to a subscription here

Parameters:

  • subscription_id (Integer)

    Required parameter: The Chargify id of

  • code (String) (defaults to: nil)

    Optional parameter: A code for the coupon that would

  • body (AddCouponsRequest) (defaults to: nil)

    Optional parameter: TODO: type description

Returns:



650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
# File 'lib/advanced_billing/controllers/subscriptions_controller.rb', line 650

def apply_coupons_to_subscription(subscription_id,
                                  code: nil,
                                  body: nil)
  @api_call
    .request(new_request_builder(HttpMethodEnum::POST,
                                 '/subscriptions/{subscription_id}/add_coupon.json',
                                 Server::PRODUCTION)
               .template_param(new_parameter(subscription_id, key: 'subscription_id')
                                .is_required(true)
                                .should_encode(true))
               .header_param(new_parameter('application/json', key: 'Content-Type'))
               .query_param(new_parameter(code, key: 'code'))
               .body_param(new_parameter(body))
               .header_param(new_parameter('application/json', key: 'accept'))
               .body_serializer(proc do |param| param.to_json unless param.nil? end)
               .auth(Single.new('BasicAuth')))
    .response(new_response_handler
                .deserializer(APIHelper.method(:custom_type_deserializer))
                .deserialize_into(SubscriptionResponse.method(:from_hash))
                .local_error_template('422',
                                      'HTTP Response Not OK. Status code: {$statusCode}.'\
                                       ' Response: \'{$response.body}\'.',
                                      SubscriptionAddCouponErrorException))
    .execute
end

#create_subscription(body: nil) ⇒ SubscriptionResponse

Creates a Subscription for a customer and product. Specify the product with product_id or product_handle. To set a specific product price point, use product_price_point_handle or product_price_point_id. Identify an existing customer with customer_id or customer_reference. Optionally, include an existing payment profile using payment_profile_id. To create a new customer, pass customer_attributes. Select an option from the Request Examples drop-down on the right side of the portal to see examples of common scenarios for creating subscriptions.

List vs Sales Pricing

When a subscription uses custom pricing as the sales price, you can optionally provide a list price for any item. If omitted, the list price defaults to the sales price. The difference between the list price and sales price is used to calculate implicit discounts, which appear on Invoices and in reporting. List price can also support revenue allocations in [Advanced Revenue](https://docs.maxio.com/hc/en-us/articles/24177001342861-Create-an d-Configure-RevenueBooks). If your site has list pricing enabled, the API accepts custom_price.list_price_point_id for custom pricing, validates and persists it, and returns list price metadata in subscription responses. If list pricing is disabled, this input is ignored and related response fields are omitted. When list pricing is enabled:

  • Subscription → Product product_price_point_list_price_point_id (integer)
  • product_price_point_list_price_point_handle (string)
  • Subscription Components (when components are included in the response, such as with subscriptions built from components or component serialization paths) component_id (integer)
  • price_point_id (integer)
  • list_price_point_id (integer) When list pricing is disabled:
  • Subscription → Product product_price_point_list_price_point_id: omitted
  • product_price_point_list_price_point_handle: omitted
  • Subscription Components list_price_point_id: omitted This functionality is supported in the API, but is not currently supported in SDKs.

Subscriptions can now work independently from the catalog

If you have the new [Catalog experience](page:help/announcements/2026-announcements#new-catalog-experie nce-and-terminology) enabled, you can create subscriptions without a product_id or product_handle using POST /subscriptions, building them entirely from components. A valid subscription must include at least one active component with:

  • a positive allocated_quantity,
  • a positive unit_balance, or
  • 'enabled: true' (for on/off components)
  • a configured metered component component_id can be provided as a numeric ID or in handle: format. If trial_interval and trial_interval_unit are included, they are applied at creation. In the response, product and product price point fields are null, and component details are returned instead. This functionality is supported in the API, but is not currently supported in SDKs.

Payment information

Payment information may be required to create a subscription, depending on the options for the Product being subscribed. See [product options](https://docs.maxio.com/hc/en-us/articles/24261076617869-Edit-Prod ucts) for more information. See the Payments Profile endpoint for details on payment parameters. See the Subscription Signups article for more information on working with subscriptions in Advanced Billing.

Payment information

Payment information may be required to create a subscription, depending on the options for the Product being subscribed. See [product options](https://docs.maxio.com/hc/en-us/articles/24261076617869-Edit-Prod ucts) for more information. See the Payments Profile endpoint for details on payment parameters. Do not use real card information for testing. See the Sites articles that cover [testing your site setup](https://docs.maxio.com/hc/en-us/articles/24250712113165-Testing-Ove rview#testing-overview-0-0) for more details on testing in your sandbox. Note that collecting and sending raw card details in production requires [PCI compliance](https://docs.maxio.com/hc/en-us/articles/24183956938381-PCI-Co mpliance#pci-compliance-0-0) on your end. If your business is not PCI compliant, use [Maxio.js (formerly Chargify.js)](https://docs.maxio.com/hc/en-us/articles/38163190843789-Char gify-js-Overview#chargify-js-overview-0-0) to collect credit card or bank account information.

3D Secure (3DS) Authentication post-authentication flow

When a payment requires 3DS Authentication to adhere to Strong Customer Authentication (SCA), the request enters a post-authentication flow where a 422 Unprocessable Entity status is returned with an action_link that will direct the customer through 3DS Authentication. See the [3D Secure Post-Authentication Flow](https://docs.maxio.com/hc/en-us/articles/44277749524365-3D-Secure-Po st-Authentication-Flow) article in the product documentation to learn how to manage the redirect flow. description here

Parameters:

Returns:



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/advanced_billing/controllers/subscriptions_controller.rb', line 108

def create_subscription(body: nil)
  @api_call
    .request(new_request_builder(HttpMethodEnum::POST,
                                 '/subscriptions.json',
                                 Server::PRODUCTION)
               .header_param(new_parameter('application/json', key: 'Content-Type'))
               .body_param(new_parameter(body))
               .header_param(new_parameter('application/json', key: 'accept'))
               .body_serializer(proc do |param| param.to_json unless param.nil? end)
               .auth(Single.new('BasicAuth')))
    .response(new_response_handler
                .deserializer(APIHelper.method(:custom_type_deserializer))
                .deserialize_into(SubscriptionResponse.method(:from_hash))
                .local_error_template('422',
                                      'HTTP Response Not OK. Status code: {$statusCode}.'\
                                       ' Response: \'{$response.body}\'.',
                                      ErrorListResponseException))
    .execute
end

#find_subscription(reference: nil) ⇒ SubscriptionResponse

Finds a subscription by its reference.

Parameters:

  • reference (String) (defaults to: nil)

    Optional parameter: Subscription reference

Returns:



470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
# File 'lib/advanced_billing/controllers/subscriptions_controller.rb', line 470

def find_subscription(reference: nil)
  @api_call
    .request(new_request_builder(HttpMethodEnum::GET,
                                 '/subscriptions/lookup.json',
                                 Server::PRODUCTION)
               .query_param(new_parameter(reference, key: 'reference'))
               .header_param(new_parameter('application/json', key: 'accept'))
               .auth(Single.new('BasicAuth')))
    .response(new_response_handler
                .deserializer(APIHelper.method(:custom_type_deserializer))
                .deserialize_into(SubscriptionResponse.method(:from_hash))
                .local_error_template('404',
                                      'Not Found:\'{$response.body}\'',
                                      APIException))
    .execute
end

#list_subscriptions(options = {}) ⇒ Array[SubscriptionResponse]

Lists subscriptions for a site. Use the query string filters and pagination to control responses from the server. If you have the new [Catalog experience](page:help/announcements/2026-announcements#new-catalog-experie nce-and-terminology) enabled, some subscriptions may not have an associated product. For subscriptions without an associated product, 'product', 'product_price_point_id', and 'product_price_point_type' are returned as 'null'.

Search for a subscription

Use the query strings below to search for a subscription using the criteria available. The return value will be an array.

Self-Service Page token

Self-Service Page token for the subscriptions is not returned by default. If this information is desired, the include=self_service_page_token parameter must be provided with the request. pages. By default, the first page of results is displayed. The page parameter specifies a page number of results to fetch. You can start navigating through the pages to consume the results. You do this by passing in a page parameter. Retrieve the next page by adding ?page=2 to the query string. If there are no results to return, then an empty result set will be returned. Use in query page=1. many records to fetch in each request. Default value is 20. The maximum allowed values is 200; any per_page value over 200 will be changed to 200. Use in query per_page=200. to sort in which results are returned. Use in query direction=asc. state of the subscription subscriptions by product. Accepts product ID or exact product name. Product handle is not supported. search. of the customer. product price point. If supplied, product is required. currently applied to the subscription. (This can be found in the URL when editing a coupon. Note that the coupon code cannot be used.) applied to the subscription collection method for the subscription. subscriptions by the ID of an assigned Branding Theme. Branding Themes is a beta feature. See [Understand Branding Themes](https://docs.maxio.com/hc/en-us/articles/43796895662093-Understand -Branding-Themes#understand-branding-themes-0-0) for more information. filter you'd like to apply to your search. Allowed Values: , current_period_ends_at, current_period_starts_at, created_at, activated_at, canceled_at, expires_at, trial_started_at, trial_ended_at, updated_at YYYY-MM-DD) with which to filter the date_field. Returns subscriptions with a timestamp at or after midnight (12:00:00 AM) in your site’s time zone on the date specified. Use in query start_date=2022-07-01. YYYY-MM-DD) with which to filter the date_field. Returns subscriptions with a timestamp up to and including 11:59:59PM in your site’s time zone on the date specified. Use in query end_date=2022-08-01. time (format YYYY-MM-DD HH:MM:SS) with which to filter the date_field. Returns subscriptions with a timestamp at or after exact time provided in query. You can specify timezone in query - otherwise your site's time zone will be used. If provided, this parameter will be used instead of start_date. Use in query start_datetime=2022-07-01 09:00:05. (format YYYY-MM-DD HH:MM:SS) with which to filter the date_field. Returns subscriptions with a timestamp at or before exact time provided in query. You can specify timezone in query - otherwise your site's time zone will be used. If provided, this parameter will be used instead of end_date. Use in query end_datetime=2022-08-01 10:00:05. the metadata field specified in the parameter. Use in query metadata[my-field]=value&metadata[other-field]=another_value. subscription is in a group. Filter by dunning exemption status. payment gateway identifiers. codes. including additional data in the response. Use in query: include[]=self_service_page_token.

Parameters:

  • page (Integer)

    Optional parameter: Result records are organized in

  • per_page (Integer)

    Optional parameter: This parameter indicates how

  • sort (SubscriptionSort)

    Optional parameter: The attribute by which

  • direction (SortingDirection)

    Optional parameter: Controls the order

  • state (SubscriptionStateFilter)

    Optional parameter: The current

  • product (Integer | String | nil)

    Optional parameter: Filter

  • q (String)

    Optional parameter: Search string.

  • q_scope (QScope)

    Optional parameter: Scope of fields used by the q

  • customer_id (Integer)

    Optional parameter: The Advanced Billing id

  • product_price_point_id (Integer)

    Optional parameter: The ID of the

  • coupon (Integer)

    Optional parameter: The numeric id of the coupon

  • coupon_code (String)

    Optional parameter: The coupon code currently

  • collection_method (CollectionMethod1)

    Optional parameter: The

  • branding_theme_id (Integer)

    Optional parameter: Filter

  • date_field (SubscriptionDateField)

    Optional parameter: The type of

  • start_date (Date)

    Optional parameter: The start date (format

  • end_date (Date)

    Optional parameter: The end date (format

  • start_datetime (DateTime)

    Optional parameter: The start date and

  • end_datetime (DateTime)

    Optional parameter: The end date and time

  • metadata (Hash[String, String])

    Optional parameter: The value of

  • group_status (GroupStatus)

    Optional parameter: Filter by whether a

  • dunning_exemption (TrueClass | FalseClass)

    Optional parameter:

  • payment_gateways (String)

    Optional parameter: Comma-separated

  • currencies (String)

    Optional parameter: Comma-separated currency

  • include (Array[SubscriptionListInclude])

    Optional parameter: Allows

Returns:



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/advanced_billing/controllers/subscriptions_controller.rb', line 222

def list_subscriptions(options = {})
  @api_call
    .request(new_request_builder(HttpMethodEnum::GET,
                                 '/subscriptions.json',
                                 Server::PRODUCTION)
               .query_param(new_parameter(options['page'], key: 'page'))
               .query_param(new_parameter(options['per_page'], key: 'per_page'))
               .query_param(new_parameter(options['sort'], key: 'sort'))
               .query_param(new_parameter(options['direction'], key: 'direction'))
               .query_param(new_parameter(options['state'], key: 'state'))
               .query_param(new_parameter(options['product'], key: 'product')
                             .validator(proc do |value|
                               UnionTypeLookUp.get(:ListSubscriptionsInputProduct)
                                              .validate(value)
                             end))
               .query_param(new_parameter(options['q'], key: 'q'))
               .query_param(new_parameter(options['q_scope'], key: 'q_scope'))
               .query_param(new_parameter(options['customer_id'], key: 'customer_id'))
               .query_param(new_parameter(options['product_price_point_id'], key: 'product_price_point_id'))
               .query_param(new_parameter(options['coupon'], key: 'coupon'))
               .query_param(new_parameter(options['coupon_code'], key: 'coupon_code'))
               .query_param(new_parameter(options['collection_method'], key: 'collection_method'))
               .query_param(new_parameter(options['branding_theme_id'], key: 'branding_theme_id'))
               .query_param(new_parameter(options['date_field'], key: 'date_field'))
               .query_param(new_parameter(options['start_date'], key: 'start_date'))
               .query_param(new_parameter(options['end_date'], key: 'end_date'))
               .query_param(new_parameter(options['start_datetime'], key: 'start_datetime'))
               .query_param(new_parameter(options['end_datetime'], key: 'end_datetime'))
               .query_param(new_parameter(options['metadata'], key: 'metadata'))
               .query_param(new_parameter(options['group_status'], key: 'group_status'))
               .query_param(new_parameter(options['dunning_exemption'], key: 'dunning_exemption'))
               .query_param(new_parameter(options['payment_gateways'], key: 'payment_gateways'))
               .query_param(new_parameter(options['currencies'], key: 'currencies'))
               .query_param(new_parameter(options['include'], key: 'include'))
               .header_param(new_parameter('application/json', key: 'accept'))
               .auth(Single.new('BasicAuth'))
               .array_serialization_format(ArraySerializationFormat::UN_INDEXED))
    .response(new_response_handler
                .deserializer(APIHelper.method(:custom_type_deserializer))
                .deserialize_into(SubscriptionResponse.method(:from_hash))
                .is_response_array(true))
    .execute
end

#override_subscription(subscription_id, body: nil) ⇒ void

This method returns an undefined value.

Sets certain subscription fields that are usually managed automatically. Some of the fields can be set via the normal Subscriptions Update API, but others can only be set using this endpoint. This endpoint is provided for cases where you need to “align” Advanced Billing data with data that happened in your system, perhaps before you started using Advanced Billing. For example, you may choose to import your historical subscription data, and would like the activation and cancellation dates in Advanced Billing to match your existing historical dates. Advanced Billing does not backfill historical events (i.e. from the Events API), but some static data can be changed via this API. Why are some fields only settable from this endpoint, and not the normal subscription create and update endpoints? Because we want users of this endpoint to be aware that these fields are usually managed by Advanced Billing, and using this API means you are stepping out on your own. Changing these fields will not affect any other attributes. For example, adding an expiration date will not affect the next assessment date on the subscription. If you regularly need to override the current_period_starts_at for new subscriptions, this can also be accomplished by setting both previous_billing_at and next_billing_at at subscription creation. See the documentation on Importing Subscriptions for more information.

Limitations

When passing current_period_starts_at some validations are made:

  1. The subscription needs to be unbilled (no statements or invoices).
  2. The value passed must be a valid date/time. We recommend using the iso 8601 format.
  3. The value passed must be before the current date/time. If unpermitted parameters are sent, a 400 HTTP response is sent along with a string giving the reason for the problem. the subscription. fields are available to be set.

Parameters:

  • subscription_id (Integer)

    Required parameter: The Chargify id of

  • body (OverrideSubscriptionRequest) (defaults to: nil)

    Optional parameter: Only these



445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
# File 'lib/advanced_billing/controllers/subscriptions_controller.rb', line 445

def override_subscription(subscription_id,
                          body: nil)
  @api_call
    .request(new_request_builder(HttpMethodEnum::PUT,
                                 '/subscriptions/{subscription_id}/override.json',
                                 Server::PRODUCTION)
               .template_param(new_parameter(subscription_id, key: 'subscription_id')
                                .is_required(true)
                                .should_encode(true))
               .header_param(new_parameter('application/json', key: 'Content-Type'))
               .body_param(new_parameter(body))
               .body_serializer(proc do |param| param.to_json unless param.nil? end)
               .auth(Single.new('BasicAuth')))
    .response(new_response_handler
                .is_response_void(true)
                .local_error_template('422',
                                      'HTTP Response Not OK. Status code: {$statusCode}.'\
                                       ' Response: \'{$response.body}\'.',
                                      SingleErrorResponseException))
    .execute
end

#preview_subscription(body: nil) ⇒ SubscriptionPreviewResponse

Previews a subscription by POSTing the same JSON or XML as for a subscription creation. The "Next Billing" amount and "Next Billing" date are represented in each Subscriber's Summary. This endpoint does not create a subscription; it is meant to serve as a prediction. For more information, see [Subscriber Interface Overview](https://maxio.zendesk.com/hc/en-us/articles/24252493695757-Subsc riber-Interface-Overview).

Subscriptions can now work independently from the catalog

If you have the new [Catalog experience](page:help/announcements/2026-announcements#new-catalog-experie nce-and-terminology) enabled, you can create subscriptions without a product_id or product_handle using POST /subscriptions, building them entirely from components. A valid subscription must include at least one active component with:

  • a positive allocated_quantity,
  • a positive unit_balance, or
  • 'enabled: true' (for on/off components) component_id can be provided as a numeric ID or in handle: format. If trial_interval and trial_interval_unit are included, they are applied at creation. In the response, product and product price point fields are null, and component details are returned instead. This functionality is supported in the API, but is not currently supported in SDKs.

Taxable Subscriptions

This endpoint previews taxes applicable to a purchase. For taxes to be previewed, the following conditions must be met:

  • Taxes must be configured on the subscription
  • The preview must be for the purchase of a taxable product or component, or combination of the two.
  • The subscription payload must contain a full billing or shipping address to calculate tax For more information about creating taxable previews, see Taxes. You do not need to include a card number to generate tax information when you are previewing a subscription. However, when you actually want to create the subscription, you must include the credit card information if you want the billing address to be stored. The billing address and the credit card information are stored together within the payment profile object. Also, you cannot send a billing address without payment profile information, as the address is stored on the card. You can pass shipping and billing addresses and still decide not to calculate taxes. To do that, pass skip_billing_manifest_taxes: true attribute.

Non-taxable Subscriptions

If you'd like to calculate subscriptions that do not include tax, you can leave off the billing information. description here

Parameters:

Returns:



613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
# File 'lib/advanced_billing/controllers/subscriptions_controller.rb', line 613

def preview_subscription(body: nil)
  @api_call
    .request(new_request_builder(HttpMethodEnum::POST,
                                 '/subscriptions/preview.json',
                                 Server::PRODUCTION)
               .header_param(new_parameter('application/json', key: 'Content-Type'))
               .body_param(new_parameter(body))
               .header_param(new_parameter('application/json', key: 'accept'))
               .body_serializer(proc do |param| param.to_json unless param.nil? end)
               .auth(Single.new('BasicAuth')))
    .response(new_response_handler
                .deserializer(APIHelper.method(:custom_type_deserializer))
                .deserialize_into(SubscriptionPreviewResponse.method(:from_hash)))
    .execute
end

#purge_subscription(subscription_id, ack, cascade: nil) ⇒ SubscriptionResponse

Purges an individual subscription for sites in test mode. Provide the subscription ID in the URL. To confirm, supply the customer ID in the query string ack parameter. You may also delete the customer record and/or payment profiles by passing cascade parameters. For example, to delete just the customer record, the query params would be: ?ack={customer_id}&cascade[]=customer If you need to remove subscriptions from a live site, contact support to discuss your use case.

Delete customer and payment profile

The query params will be: ?ack={customer_id}&cascade[]=customer&cascade[]=payment_profile the subscription. are "customer" or "payment_profile". Use in query: cascade[]=customer&cascade[]=payment_profile.

Parameters:

  • subscription_id (Integer)

    Required parameter: The Chargify id of

  • ack (Integer)

    Required parameter: id of the customer.

  • cascade (Array[SubscriptionPurgeType]) (defaults to: nil)

    Optional parameter: Options

Returns:



505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
# File 'lib/advanced_billing/controllers/subscriptions_controller.rb', line 505

def purge_subscription(subscription_id,
                       ack,
                       cascade: nil)
  @api_call
    .request(new_request_builder(HttpMethodEnum::POST,
                                 '/subscriptions/{subscription_id}/purge.json',
                                 Server::PRODUCTION)
               .template_param(new_parameter(subscription_id, key: 'subscription_id')
                                .is_required(true)
                                .should_encode(true))
               .query_param(new_parameter(ack, key: 'ack')
                             .is_required(true))
               .query_param(new_parameter(cascade, key: 'cascade'))
               .header_param(new_parameter('application/json', key: 'accept'))
               .auth(Single.new('BasicAuth'))
               .array_serialization_format(ArraySerializationFormat::UN_INDEXED))
    .response(new_response_handler
                .deserializer(APIHelper.method(:custom_type_deserializer))
                .deserialize_into(SubscriptionResponse.method(:from_hash))
                .local_error_template('400',
                                      'HTTP Response Not OK. Status code: {$statusCode}.'\
                                       ' Response: \'{$response.body}\'.',
                                      SubscriptionResponseErrorException))
    .execute
end

#read_subscription(subscription_id, include: nil) ⇒ SubscriptionResponse

Retrieves subscription details. If you have the new [Catalog experience](page:help/announcements/2026-announcements#new-catalog-experie nce-and-terminology) enabled, some subscriptions may not have an associated product. For subscriptions without an associated product, 'product', 'product_price_point_id', and 'product_price_point_type' are returned as 'null'.

Self-Service Page token

Self-Service Page token for the subscription is not returned by default. If this information is desired, the include=self_service_page_token parameter must be provided with the request. the subscription. including additional data in the response. Use in query: include[]=coupons&include[]=self_service_page_token.

Parameters:

  • subscription_id (Integer)

    Required parameter: The Chargify id of

  • include (Array[SubscriptionInclude]) (defaults to: nil)

    Optional parameter: Allows

Returns:



390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
# File 'lib/advanced_billing/controllers/subscriptions_controller.rb', line 390

def read_subscription(subscription_id,
                      include: nil)
  @api_call
    .request(new_request_builder(HttpMethodEnum::GET,
                                 '/subscriptions/{subscription_id}.json',
                                 Server::PRODUCTION)
               .template_param(new_parameter(subscription_id, key: 'subscription_id')
                                .is_required(true)
                                .should_encode(true))
               .query_param(new_parameter(include, key: 'include'))
               .header_param(new_parameter('application/json', key: 'accept'))
               .auth(Single.new('BasicAuth'))
               .array_serialization_format(ArraySerializationFormat::UN_INDEXED))
    .response(new_response_handler
                .deserializer(APIHelper.method(:custom_type_deserializer))
                .deserialize_into(SubscriptionResponse.method(:from_hash)))
    .execute
end

#remove_coupon_from_subscription(subscription_id, coupon_code: nil) ⇒ String

Removes a coupon from an existing subscription. For more information on the expected behavior of removing a coupon from a subscription, see [Coupons and Subscriptions](https://maxio.zendesk.com/hc/en-us/articles/24261259337101- Coupons-and-Subscriptions#removing-a-coupon). the subscription.

Parameters:

  • subscription_id (Integer)

    Required parameter: The Chargify id of

  • coupon_code (String) (defaults to: nil)

    Optional parameter: The coupon code

Returns:

  • (String)

    Response from the API call.



685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
# File 'lib/advanced_billing/controllers/subscriptions_controller.rb', line 685

def remove_coupon_from_subscription(subscription_id,
                                    coupon_code: nil)
  @api_call
    .request(new_request_builder(HttpMethodEnum::DELETE,
                                 '/subscriptions/{subscription_id}/remove_coupon.json',
                                 Server::PRODUCTION)
               .template_param(new_parameter(subscription_id, key: 'subscription_id')
                                .is_required(true)
                                .should_encode(true))
               .query_param(new_parameter(coupon_code, key: 'coupon_code'))
               .auth(Single.new('BasicAuth')))
    .response(new_response_handler
                .deserializer(APIHelper.method(:deserialize_primitive_types))
                .deserialize_into(proc do |response| response&.to_s end)
                .is_primitive_response(true)
                .local_error_template('422',
                                      'HTTP Response Not OK. Status code: {$statusCode}.'\
                                       ' Response: \'{$response.body}\'.',
                                      SubscriptionRemoveCouponErrorsException))
    .execute
end

#update_prepaid_subscription_configuration(subscription_id, body: nil) ⇒ PrepaidConfigurationResponse

Updates a subscription's prepaid configuration. the subscription. type description here

Parameters:

Returns:



537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
# File 'lib/advanced_billing/controllers/subscriptions_controller.rb', line 537

def update_prepaid_subscription_configuration(subscription_id,
                                              body: nil)
  @api_call
    .request(new_request_builder(HttpMethodEnum::POST,
                                 '/subscriptions/{subscription_id}/prepaid_configurations.json',
                                 Server::PRODUCTION)
               .template_param(new_parameter(subscription_id, key: 'subscription_id')
                                .is_required(true)
                                .should_encode(true))
               .header_param(new_parameter('application/json', key: 'Content-Type'))
               .body_param(new_parameter(body))
               .header_param(new_parameter('application/json', key: 'accept'))
               .body_serializer(proc do |param| param.to_json unless param.nil? end)
               .auth(Single.new('BasicAuth')))
    .response(new_response_handler
                .deserializer(APIHelper.method(:custom_type_deserializer))
                .deserialize_into(PrepaidConfigurationResponse.method(:from_hash))
                .local_error_template('422',
                                      'HTTP Response Not OK. Status code: {$statusCode}.'\
                                       ' Response: \'{$response.body}\'.',
                                      APIException))
    .execute
end

#update_subscription(subscription_id, body: nil) ⇒ SubscriptionResponse

Updates one or more attributes of a subscription.

Update Subscription Payment Method

Change the card that your subscriber uses for their subscription. You can also use this method to change the expiration date of the card if your gateway allows. Do not use real card information for testing. See the Sites articles that cover [testing your site setup](https://docs.maxio.com/hc/en-us/articles/24250712113165-Testing-Ove rview#testing-overview-0-0) for more details on testing in your sandbox. Note that collecting and sending raw card details in production requires [PCI compliance](https://docs.maxio.com/hc/en-us/articles/24183956938381-PCI-Co mpliance#pci-compliance-0-0) on your end. If your business is not PCI compliant, use [Chargify.js](https://docs.maxio.com/hc/en-us/articles/38163190843789-Char gify-js-Overview#chargify-js-overview-0-0) to collect credit card or bank account information.

Note: Partial card updates for Authorize.Net are not allowed via this endpoint. The existing Payment Profile must be directly updated instead.

Update Product

You also use this method to change the subscription to a different product by setting a new value for product_handle. A product change can be done in two different ways, product change or delayed product change.

Product Change

You can change a subscription's product. The new payment amount is calculated and charged at the normal start of the next period. If you require complex product changes or prorated upgrades and downgrades instead, please see the documentation on [Migrating Subscription Products](https://docs.maxio.com/hc/en-us/articles/24252069837581-Product- Changes-and-Migrations#product-changes-and-migrations-0-0). To perform a product change, set either the product_handle or product_id attribute to that of a different product from the same site as the subscription. You can also change the price point by passing in either product_price_point_id or product_price_point_handle - otherwise the new product's default price point is used.

Delayed Product Change

This method also changes the product and/or price point, and the new payment amount is calculated and charged at the normal start of the next period. This method schedules the product change to happen automatically at the subscription’s next renewal date. To perform a delayed product change, set the product_handle attribute as you would in a regular product change, but also set the product_change_delayed attribute to true. No proration applies in this case. You can also perform a delayed change to the price point by passing in either product_price_point_id or product_price_point_handle

Note: To cancel a delayed product change, set next_product_id to an empty string.

Billing Date Changes

You can update dates for a subscription.

Regular Billing Date Changes

Send the next_billing_at to set the next billing date for the subscription. After that date passes and the subscription is processed, the following billing date will be set according to the subscription's product period.

Note: If you pass an invalid date, the correct date is automatically set to the correct date. For example, if February 30 is passed, the next billing would be set to March 2nd in a non-leap year. The server response will not return data under the key/value pair of next_billing_at. View the key/value pair of current_period_ends_at to verify that the next_billing_at date has been changed successfully.

Calendar Billing and Snap Day Changes

For a subscription using Calendar Billing, setting the next billing date is a bit different. Send the snap_day attribute to change the calendar billing date for a subscription using a product eligible for calendar billing.

Note: If you change the product associated with a subscription that contains a snap_day and immediately READ/GET the subscription data, it will still contain the original snap_day. The snap_day will be reset to null on the next billing cycle. This is because a product change is instantaneous and only affects the product associated with a subscription. If you have the new [Catalog experience](page:help/announcements/2026-announcements#new-catalog-experie nce-and-terminology) enabled, some subscriptions may not have an associated product. For subscriptions without an associated product, product, product_price_point_id, and product_price_point_type are returned as null. the subscription. description here

Parameters:

  • subscription_id (Integer)

    Required parameter: The Chargify id of

  • body (UpdateSubscriptionRequest) (defaults to: nil)

    Optional parameter: TODO: type

Returns:



349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
# File 'lib/advanced_billing/controllers/subscriptions_controller.rb', line 349

def update_subscription(subscription_id,
                        body: nil)
  @api_call
    .request(new_request_builder(HttpMethodEnum::PUT,
                                 '/subscriptions/{subscription_id}.json',
                                 Server::PRODUCTION)
               .template_param(new_parameter(subscription_id, key: 'subscription_id')
                                .is_required(true)
                                .should_encode(true))
               .header_param(new_parameter('application/json', key: 'Content-Type'))
               .body_param(new_parameter(body))
               .header_param(new_parameter('application/json', key: 'accept'))
               .body_serializer(proc do |param| param.to_json unless param.nil? end)
               .auth(Single.new('BasicAuth')))
    .response(new_response_handler
                .deserializer(APIHelper.method(:custom_type_deserializer))
                .deserialize_into(SubscriptionResponse.method(:from_hash))
                .local_error_template('422',
                                      'HTTP Response Not OK. Status code: {$statusCode}.'\
                                       ' Response: \'{$response.body}\'.',
                                      ErrorListResponseException))
    .execute
end