> ## Documentation Index
> Fetch the complete documentation index at: https://docs.billbuddyhq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a hosted subscription

> ### Choose a subscription mode

Use the recommended nested `customer` and `plan` fields. Choose one customer format: `customer.customer_id` for an existing customer, or `customer.firstName`, `customer.lastName` and `customer.emailAddress` for a new customer. Do not combine existing customer identification with new customer details.

| Mode | Fields to supply | Conditions |
| --- | --- | --- |
| Manual subscription | `plan.plan_name` and at least one enabled `plan.recurring` or `plan.one_off` segment | Set each enabled segment's `enabled` to 1; recurring and one-off segments can both be enabled |
| Template subscription | `plan.template_id` and the applicable template dates | Supply `plan.start_date` for a recurring segment and `plan.payment_date` for a one-off segment; omit `plan_name` to inherit the template name |
| By agreement | `plan.plan_name` and `plan.schedule` | Supply `schedule_name`, `type`, `amount` and `start_date` for the initial schedule; types 1, 2, 3, 4 and 6 are allowed |

The three modes are mutually exclusive. An enabled manual recurring segment requires `schedule_name`, `recurring_type`, `amount`, `start_date` and `day_of_debit`. An enabled one-off segment requires `schedule_name`, `amount` and `payment_date`. Dates must be no earlier than tomorrow in the business timezone.

| Recurring end condition | Additional required fields |
| --- | --- |
| `recurring_type=1` / `schedule.type=1`, successful payment count | `end_terms` |
| `recurring_type=2` / `schedule.type=2`, total amount | `total_amount`, with `amount` no greater than `total_amount` |
| `recurring_type=3` / `schedule.type=3`, until cancelled | No additional end condition |
| `recurring_type=4` / `schedule.type=4`, end date | `end_date`, no earlier than the same segment's `start_date` |
| `schedule.type=6`, one-off | `day_of_debit` is not required; this type is not available for `recurring_type` |

Quarterly, half-yearly and yearly frequencies require `day_of_debit_dtstart`. Custom frequencies require `process_type=12`, `custom_cycle_type` and `custom_cycle`, consistent with the RRULE. See individual fields for ranges and date windows.

Top-level alternative fields remain supported. New integrations should use the nested format consistently. If both formats contain the same field, the nested value takes precedence.

A successful creation returns status=2 Inactive; the subscription is not yet activated. Give customers the complete activation_url unchanged, use it as an iframe src, or use activation_html as the iframe srcdoc. Customers enter payment details, authorize debits and activate on the BillBuddy-hosted page. Do not construct activation links or parse credentials. Keep the Client Secret and access_token on your server. Three definition modes are mutually exclusive: manual recurring/one_off, template_id, and By agreement schedule. Template mode requires dates for each enabled component: recurring start_date and one-off payment_date. New customer details and existing customer references are mutually exclusive. The nested customer/plan format is recommended; see field descriptions for alternatives. A successful response may omit the activation link. Contact BillBuddy to check the created subscription before proceeding in that case. No caller-supplied idempotency identifier is supported; do not blindly retry creation. Recurring and By agreement subscriptions must be activated before start_date; one-off-only subscriptions must be submitted for activation within 30 days of creation. An accessible page does not guarantee submission is still permitted; the activation response is authoritative.

All examples illustrate request and response formats. Replace customers, orders, cards and accounts with approved test data. BASE_URL is the service root domain without /api/v2. ACCESS_TOKEN is the access_token returned by /oauth/token. Example dates are in 2030; replace them with actual dates that satisfy the current date restrictions.



## OpenAPI

````yaml /openapi/billbuddy-v2-openapi.en.yaml post /api/v2/subscription/create
openapi: 3.0.3
info:
  title: BillBuddy API Integration Guide
  version: 2.0.0
  description: >
    BillBuddy API integration guide. It covers authentication, transaction and
    subscription endpoints called by third-party servers. Request and response
    examples contain complete fictional business data and tokens generated
    offline; they cannot authenticate or initiate real transactions.


    ## Getting started

    1. Obtain your Client ID, Client Secret, merchant identifier and business
    identifier from BillBuddy. If an IP allowlist applies, send requests from an
    approved fixed outbound IP address.

    2. Obtain an access_token through POST /oauth/token. Business requests
    require Authorization: Bearer {access_token} and Accept: application/json.
    Use Content-Type: application/json for JSON requests and form encoding for
    token requests.

    3. Call the payment or subscription endpoints as needed. Customers open the
    hosted activation page through activation_url. Store the Client Secret only
    on your server.


    ## Identifiers and amounts

    OAuth credentials identify the merchant; business_id is not a request
    parameter. Endpoints that require a business use merchant_id. For
    single-transaction and batch-result lookups, merchant_id is optional; omit
    it or leave it empty to search all businesses of the authenticated merchant.
    The transaction list uses optional, case-sensitive Mid; omit it to query all
    businesses belonging to the authenticated merchant. A requested business
    must belong to that merchant. Read response identifiers according to each
    endpoint's field definitions.

    TXT file amounts, amount_cents and declared_total_amount_cents use cents.
    Other amounts use major currency units with at most two decimal places:
    10.50 means AUD 10.50. Use strings for bank account numbers, card numbers,
    months, years and postcodes to preserve leading zeros.


    ## Success and failure

    Business JSON responses use code=0 for success and code=1 for ordinary
    failures. Transaction and subscription validation failures usually return
    code=400 and data={} with HTTP 200. V2 business endpoint authentication
    failures use code=1. A missing, malformed or inaccessible business
    merchant_id for plan/list return code=1. HTTP 429 indicates a rate limit.
    The OAuth endpoint uses standard OAuth responses with HTTP 200/400/401/429.

    code=0 means the API request was processed successfully; assess the payment
    outcome separately. Batch accepted means the request was accepted for
    asynchronous processing. Bank Pending, scheduled Pending and outstanding 3DS
    authentication do not indicate payment success. Transactions, DDR
    subscriptions and payment schedules use different status enumerations; refer
    to their field definitions.


    ## Dates and frequencies

    Use YYYY-MM-DD for request dates. Today and tomorrow are evaluated in
    Australia/Sydney, including daylight saving time. Scheduled cancellations
    also use Australia/Sydney: cancellation must occur strictly before 08:15 on
    the processing date; it is no longer permitted at that time. Payment
    complete_date and checkout expires_at use DD/MM/YYYY HH:mm:ss. Refer to
    individual fields for other formats.

    Standard RRULE examples: Daily FREQ=DAILY;INTERVAL=1; Weekly
    FREQ=WEEKLY;INTERVAL=1;BYDAY=MO; Fortnightly
    FREQ=WEEKLY;INTERVAL=2;BYDAY=MO; Monthly
    FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=15; Quarterly
    FREQ=MONTHLY;INTERVAL=3;BYMONTHDAY=15; Half Yearly
    FREQ=MONTHLY;INTERVAL=6;BYMONTHDAY=15; Yearly
    FREQ=YEARLY;INTERVAL=1;BYMONTH=2;BYMONTHDAY=15. Weekday abbreviations are
    MO/TU/WE/TH/FR/SA/SU. Weekly/Monthly rules without a specific debit day
    derive it from the start date. A single BYDAY=SA or SU is treated as Monday;
    a weekend start date without an explicit debit day is also treated as
    Monday. A single BYMONTHDAY=29/30/31 falls on the last day of shorter
    months; BYMONTHDAY=-1 means the last day of the month. All rules must be
    valid RRULE expressions.

    For a nonstandard frequency such as every 10 days, provide process_type=12,
    custom_cycle_type=1, custom_cycle=10 and
    day_of_debit=FREQ=DAILY;INTERVAL=10. Units 1/2/3/4 correspond to
    DAILY/WEEKLY/MONTHLY/YEARLY. The minimum interval is 5 for days and 1 for
    other units. INTERVAL must equal custom_cycle. Quarterly, half-yearly and
    yearly schedules also require day_of_debit_dtstart. Its complete date must
    be strictly after the start_date of the same schedule segment and within one
    billing cycle after it. The first actual debit date for createSchedule
    depends on the DDR start date, debit frequency and the requirement that it
    be no earlier than tomorrow.


    ## Using examples

    Schemas define types, nullability, lengths, enumerations and numeric ranges.
    Field descriptions define conditional requirements, dates and business
    restrictions. Use both together. Set BASE_URL, ACCESS_TOKEN, CLIENT_ID and
    CLIENT_SECRET before running curl examples. BillBuddy provides the actual
    test and production domains. Replace example customers, orders, cards,
    accounts and dates with values permitted in your test environment and
    satisfying the date restrictions.


    ## Hosted subscription integration

    Call POST /api/v2/subscription/create, then use the complete activation_url
    unchanged for a browser redirect or an iframe src. Alternatively, use
    activation_html as the iframe srcdoc. Customers enter payment information,
    authorize debits and activate the subscription on the BillBuddy-hosted page.
    Use the full returned URL; do not construct it yourself or parse its
    credentials. Keep the Client Secret and access_token on your server; never
    include them in iframe URLs or page contents.


    Recurring and By agreement subscriptions must be activated before
    start_date. One-off-only subscriptions must be submitted for activation
    within 30 days of creation. An accessible page does not guarantee submission
    is still permitted; the activation response is authoritative.


    ## Example data conventions

    Example merchants, customers, orders, payment tokens, session links and
    OAuth credentials are fictional and cannot be used for real requests. Card
    numbers are standard test card numbers; bank accounts are fictional. Email
    addresses use the reserved example.com domain, and phone numbers use
    Australian numbers reserved for examples. Replace BASE_URL, ACCESS_TOKEN,
    CLIENT_ID and CLIENT_SECRET with actual values from your approved test
    environment. Empty strings, null, empty arrays, 0 and false represent
    meaningful API states in some examples and must not be replaced
    indiscriminately.

    Payment response signatures are calculated offline according to the signing
    rules for each payment scenario, using the public demo key
    bb_docs_demo_signing_key_2030. The html field is excluded for responses
    awaiting 3DS authentication. This key is for documentation only and cannot
    sign or authenticate real requests.


    ## TXT batch transactions

    Upload fixed-width TXT files using multipart/form-data. File amounts,
    amount_cents and declared_total_amount_cents use cents, excluding
    surcharges; see “Upload a TXT transaction file” for the format and example
    file. Upload success only confirms acceptance. Retain batch_id and
    file_identifier and use the batch result endpoint to check individual
    outcomes. Batch completed does not mean every payment succeeded. Use OAuth
    credentials for the same merchant to query results. merchant_id is optional;
    when supplied, it must match the business identifier in the original upload.
    Response identifiers follow the definitions for each endpoint.


    ## Request examples by programming language

    Examples are provided in cURL, Python, JavaScript, PHP, Go, Java and Ruby,
    with the same business scenarios available in each language. Each example
    preserves the parameters and types from its corresponding cURL scenario.


    Requirements: cURL; Python 3.9+ (standard library); JavaScript with Node.js
    18+, saved as an .mjs file; PHP 8+ with the cURL extension; Go 1.20+; Java
    11+ (save the Example class as Example.java); Ruby 3+ (standard library).


    Set BASE_URL before running examples. Business endpoints also require
    ACCESS_TOKEN; token requests require CLIENT_ID and CLIENT_SECRET. BASE_URL
    is the API root without /api/v2. TXT upload examples read payments.txt from
    the current directory. Replace fictional values with approved test data and
    assess the response code and business status separately.
servers:
  - url: https://staging-api.billbuddyhq.com
    description: Staging environment
security:
  - oauth2: []
tags:
  - name: Authentication
    description: OAuth2 Client Credentials。
  - name: Transactions
    description: Single payments, batch payments and scheduled payment cancellations.
  - name: Subscriptions
    description: >-
      Subscription templates, hosted subscription creation, DDR creation and
      activation, and payment schedule submission.
paths:
  /api/v2/subscription/create:
    post:
      tags:
        - Subscriptions
      summary: Create a hosted subscription
      description: >-
        ### Choose a subscription mode


        Use the recommended nested `customer` and `plan` fields. Choose one
        customer format: `customer.customer_id` for an existing customer, or
        `customer.firstName`, `customer.lastName` and `customer.emailAddress`
        for a new customer. Do not combine existing customer identification with
        new customer details.


        | Mode | Fields to supply | Conditions |

        | --- | --- | --- |

        | Manual subscription | `plan.plan_name` and at least one enabled
        `plan.recurring` or `plan.one_off` segment | Set each enabled segment's
        `enabled` to 1; recurring and one-off segments can both be enabled |

        | Template subscription | `plan.template_id` and the applicable template
        dates | Supply `plan.start_date` for a recurring segment and
        `plan.payment_date` for a one-off segment; omit `plan_name` to inherit
        the template name |

        | By agreement | `plan.plan_name` and `plan.schedule` | Supply
        `schedule_name`, `type`, `amount` and `start_date` for the initial
        schedule; types 1, 2, 3, 4 and 6 are allowed |


        The three modes are mutually exclusive. An enabled manual recurring
        segment requires `schedule_name`, `recurring_type`, `amount`,
        `start_date` and `day_of_debit`. An enabled one-off segment requires
        `schedule_name`, `amount` and `payment_date`. Dates must be no earlier
        than tomorrow in the business timezone.


        | Recurring end condition | Additional required fields |

        | --- | --- |

        | `recurring_type=1` / `schedule.type=1`, successful payment count |
        `end_terms` |

        | `recurring_type=2` / `schedule.type=2`, total amount | `total_amount`,
        with `amount` no greater than `total_amount` |

        | `recurring_type=3` / `schedule.type=3`, until cancelled | No
        additional end condition |

        | `recurring_type=4` / `schedule.type=4`, end date | `end_date`, no
        earlier than the same segment's `start_date` |

        | `schedule.type=6`, one-off | `day_of_debit` is not required; this type
        is not available for `recurring_type` |


        Quarterly, half-yearly and yearly frequencies require
        `day_of_debit_dtstart`. Custom frequencies require `process_type=12`,
        `custom_cycle_type` and `custom_cycle`, consistent with the RRULE. See
        individual fields for ranges and date windows.


        Top-level alternative fields remain supported. New integrations should
        use the nested format consistently. If both formats contain the same
        field, the nested value takes precedence.


        A successful creation returns status=2 Inactive; the subscription is not
        yet activated. Give customers the complete activation_url unchanged, use
        it as an iframe src, or use activation_html as the iframe srcdoc.
        Customers enter payment details, authorize debits and activate on the
        BillBuddy-hosted page. Do not construct activation links or parse
        credentials. Keep the Client Secret and access_token on your server.
        Three definition modes are mutually exclusive: manual recurring/one_off,
        template_id, and By agreement schedule. Template mode requires dates for
        each enabled component: recurring start_date and one-off payment_date.
        New customer details and existing customer references are mutually
        exclusive. The nested customer/plan format is recommended; see field
        descriptions for alternatives. A successful response may omit the
        activation link. Contact BillBuddy to check the created subscription
        before proceeding in that case. No caller-supplied idempotency
        identifier is supported; do not blindly retry creation. Recurring and By
        agreement subscriptions must be activated before start_date;
        one-off-only subscriptions must be submitted for activation within 30
        days of creation. An accessible page does not guarantee submission is
        still permitted; the activation response is authoritative.


        All examples illustrate request and response formats. Replace customers,
        orders, cards and accounts with approved test data. BASE_URL is the
        service root domain without /api/v2. ACCESS_TOKEN is the access_token
        returned by /oauth/token. Example dates are in 2030; replace them with
        actual dates that satisfy the current date restrictions.
      operationId: v2SubscriptionCreate
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubscriptionCreateRequest'
            examples:
              manual:
                summary: Manually defined recurring subscription
                value:
                  merchant_id: '48290713'
                  customer:
                    customer_id: CUS48290713
                  plan:
                    plan_name: Monthly membership
                    recurring:
                      enabled: 1
                      schedule_name: Monthly fee
                      recurring_type: 3
                      amount: '25.50'
                      start_date: '2030-01-10'
                      day_of_debit: FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=15
                    surcharge_config: []
                  notify_email: false
                  notify_sms: false
              newCustomer:
                summary: New customer with a one-off subscription
                value:
                  merchant_id: '48290713'
                  customer:
                    firstName: Emily
                    lastName: Carter
                    emailAddress: emily.carter@example.com
                    mobilePhoneNumber: 491570006
                    addressLine1: 18 Paperbark Avenue
                    addressSuburb: Sydney
                    addressState: NSW
                    addressPostCode: '2000'
                  plan:
                    plan_name: One time fee
                    one_off:
                      enabled: 1
                      schedule_name: Initial fee
                      amount: '20.00'
                      payment_date: '2030-01-15'
              template:
                summary: Subscription from a template
                value:
                  merchant_id: '48290713'
                  customer:
                    customer_id: CUS48290713
                  plan:
                    template_id: TPL62038591
                    start_date: '2030-01-10'
              agreement:
                summary: Initial By agreement schedule
                value:
                  merchant_id: '48290713'
                  customer:
                    customer_id: CUS48290713
                  plan:
                    plan_name: Usage based DDR
                    schedule:
                      type: 6
                      schedule_name: First usage charge
                      amount: '10.00'
                      start_date: '2030-01-15'
              custom:
                summary: 'Custom frequency: every ten days'
                value:
                  merchant_id: '48290713'
                  customer:
                    customer_id: CUS48290713
                  plan:
                    plan_name: Every ten days
                    recurring:
                      enabled: 1
                      schedule_name: Ten-day membership fee
                      recurring_type: 3
                      amount: '25.50'
                      start_date: '2030-01-10'
                      day_of_debit: FREQ=DAILY;INTERVAL=10
                      process_type: 12
                      custom_cycle_type: 1
                      custom_cycle: 10
              quarterly:
                summary: Quarterly frequency with a first debit anchor
                value:
                  merchant_id: '48290713'
                  customer:
                    customer_id: CUS48290713
                  plan:
                    plan_name: Quarterly membership
                    recurring:
                      enabled: 1
                      schedule_name: Quarterly membership fee
                      recurring_type: 3
                      amount: '25.50'
                      start_date: '2030-01-10'
                      day_of_debit: FREQ=MONTHLY;INTERVAL=3;BYMONTHDAY=15
                      day_of_debit_dtstart: '2030-02-15'
      responses:
        '200':
          description: >-
            HTTP 200. Distinguish success, business errors, validation errors
            and business authentication errors using the response body code.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/SubscriptionCreateResponse'
                  - $ref: '#/components/schemas/BusinessError'
              examples:
                success:
                  summary: Subscription awaiting activation
                  value:
                    code: 0
                    message: ok
                    data:
                      customer_id: CUS48290713
                      plan_id: DDR73019482
                      status: 2
                      activation_url: >-
                        https://staging-api.billbuddyhq.com/api/v2/subscription/activatePage/73a9c4f128d60b5e9a2746cd801fb352
                      activation_html: >-
                        <!DOCTYPE html><html><head><meta charset="UTF-8"><meta
                        http-equiv="refresh"
                        content="0;url=https://staging-api.billbuddyhq.com/api/v2/subscription/activatePage/73a9c4f128d60b5e9a2746cd801fb352"><style>html,body{height:100%;margin:0}body{display:flex;align-items:center;justify-content:center;font-family:-apple-system,Segoe
                        UI,Roboto,Arial,sans-serif;color:#444;background:#fff}.tip{text-align:center;font-size:16px}.spin{width:28px;height:28px;margin:0
                        auto 12px;border:3px solid
                        #ddd;border-top-color:#888;border-radius:50%;animation:r
                        .8s linear infinite}@keyframes
                        r{to{transform:rotate(360deg)}}</style></head><body><div
                        class="tip"><div
                        class="spin"></div>Redirecting...</div><form
                        method="get"
                        action="https://staging-api.billbuddyhq.com/api/v2/subscription/activatePage/73a9c4f128d60b5e9a2746cd801fb352"
                        target="_self" id="checkform"
                        name="checkform"></form><script>window.onload=function(){document.checkform.submit();};</script></body></html>
                agreement:
                  summary: By agreement subscription awaiting activation
                  value:
                    code: 0
                    message: ok
                    data:
                      customer_id: CUS48290713
                      plan_id: DDR73019482
                      status: 2
                      activation_url: >-
                        https://staging-api.billbuddyhq.com/api/v2/subscription/activatePage/73a9c4f128d60b5e9a2746cd801fb352
                      activation_html: >-
                        <!DOCTYPE html><html><head><meta charset="UTF-8"><meta
                        http-equiv="refresh"
                        content="0;url=https://staging-api.billbuddyhq.com/api/v2/subscription/activatePage/73a9c4f128d60b5e9a2746cd801fb352"><style>html,body{height:100%;margin:0}body{display:flex;align-items:center;justify-content:center;font-family:-apple-system,Segoe
                        UI,Roboto,Arial,sans-serif;color:#444;background:#fff}.tip{text-align:center;font-size:16px}.spin{width:28px;height:28px;margin:0
                        auto 12px;border:3px solid
                        #ddd;border-top-color:#888;border-radius:50%;animation:r
                        .8s linear infinite}@keyframes
                        r{to{transform:rotate(360deg)}}</style></head><body><div
                        class="tip"><div
                        class="spin"></div>Redirecting...</div><form
                        method="get"
                        action="https://staging-api.billbuddyhq.com/api/v2/subscription/activatePage/73a9c4f128d60b5e9a2746cd801fb352"
                        target="_self" id="checkform"
                        name="checkform"></form><script>window.onload=function(){document.checkform.submit();};</script></body></html>
                      is_by_agreement: true
                withoutTicket:
                  summary: Subscription created without an activation link
                  value:
                    code: 0
                    message: ok
                    data:
                      customer_id: CUS48290713
                      plan_id: DDR73019482
                      status: 2
                failure:
                  summary: Customer not found
                  value:
                    code: 1
                    message: Customer not found
                    data: []
                validation:
                  summary: Conflicting definition modes
                  value:
                    code: 400
                    message: >-
                      Provide exactly one of: recurring/one_off, template_id, or
                      schedule.
                    data: {}
        '429':
          description: >-
            Rate limit exceeded. API requests share a limit of 120 requests per
            minute, normally counted by source IP; this is not a separate
            allowance for each endpoint. Wait for the seconds specified by
            Retry-After.
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                description: Rate limit response.
                properties:
                  message:
                    type: string
                    description: Rate limit message.
              example:
                message: Too Many Attempts.
      security:
        - oauth2: []
      x-codeSamples:
        - lang: Shell
          label: Manually defined recurring subscription
          source: |-
            curl -X POST "${BASE_URL}/api/v2/subscription/create" \
              -H "Authorization: Bearer ${ACCESS_TOKEN}" \
              -H "Accept: application/json" \
              -H "Content-Type: application/json" \
              --data-raw '{
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Monthly membership",
                "recurring": {
                  "enabled": 1,
                  "schedule_name": "Monthly fee",
                  "recurring_type": 3,
                  "amount": "25.50",
                  "start_date": "2030-01-10",
                  "day_of_debit": "FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=15"
                },
                "surcharge_config": []
              },
              "notify_email": false,
              "notify_sms": false
            }'
        - lang: Shell
          label: New customer with a one-off subscription
          source: |-
            curl -X POST "${BASE_URL}/api/v2/subscription/create" \
              -H "Authorization: Bearer ${ACCESS_TOKEN}" \
              -H "Accept: application/json" \
              -H "Content-Type: application/json" \
              --data-raw '{
              "merchant_id": "48290713",
              "customer": {
                "firstName": "Emily",
                "lastName": "Carter",
                "emailAddress": "emily.carter@example.com",
                "mobilePhoneNumber": "0491570006",
                "addressLine1": "18 Paperbark Avenue",
                "addressSuburb": "Sydney",
                "addressState": "NSW",
                "addressPostCode": "2000"
              },
              "plan": {
                "plan_name": "One time fee",
                "one_off": {
                  "enabled": 1,
                  "schedule_name": "Initial fee",
                  "amount": "20.00",
                  "payment_date": "2030-01-15"
                }
              }
            }'
        - lang: Shell
          label: Subscription from a template
          source: |-
            curl -X POST "${BASE_URL}/api/v2/subscription/create" \
              -H "Authorization: Bearer ${ACCESS_TOKEN}" \
              -H "Accept: application/json" \
              -H "Content-Type: application/json" \
              --data-raw '{
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "template_id": "TPL62038591",
                "start_date": "2030-01-10"
              }
            }'
        - lang: Shell
          label: Initial By agreement schedule
          source: |-
            curl -X POST "${BASE_URL}/api/v2/subscription/create" \
              -H "Authorization: Bearer ${ACCESS_TOKEN}" \
              -H "Accept: application/json" \
              -H "Content-Type: application/json" \
              --data-raw '{
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Usage based DDR",
                "schedule": {
                  "type": 6,
                  "schedule_name": "First usage charge",
                  "amount": "10.00",
                  "start_date": "2030-01-15"
                }
              }
            }'
        - lang: Shell
          label: 'Custom frequency: every ten days'
          source: |-
            curl -X POST "${BASE_URL}/api/v2/subscription/create" \
              -H "Authorization: Bearer ${ACCESS_TOKEN}" \
              -H "Accept: application/json" \
              -H "Content-Type: application/json" \
              --data-raw '{
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Every ten days",
                "recurring": {
                  "enabled": 1,
                  "schedule_name": "Ten-day membership fee",
                  "recurring_type": 3,
                  "amount": "25.50",
                  "start_date": "2030-01-10",
                  "day_of_debit": "FREQ=DAILY;INTERVAL=10",
                  "process_type": 12,
                  "custom_cycle_type": 1,
                  "custom_cycle": 10
                }
              }
            }'
        - lang: Shell
          label: Quarterly frequency with a first debit anchor
          source: |-
            curl -X POST "${BASE_URL}/api/v2/subscription/create" \
              -H "Authorization: Bearer ${ACCESS_TOKEN}" \
              -H "Accept: application/json" \
              -H "Content-Type: application/json" \
              --data-raw '{
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Quarterly membership",
                "recurring": {
                  "enabled": 1,
                  "schedule_name": "Quarterly membership fee",
                  "recurring_type": 3,
                  "amount": "25.50",
                  "start_date": "2030-01-10",
                  "day_of_debit": "FREQ=MONTHLY;INTERVAL=3;BYMONTHDAY=15",
                  "day_of_debit_dtstart": "2030-02-15"
                }
              }
            }'
        - lang: Python
          label: Manually defined recurring subscription
          source: >
            import json

            import os

            import urllib.parse

            import urllib.request


            base_url = os.environ["BASE_URL"].rstrip("/")

            url = base_url + "/api/v2/subscription/create"

            headers = {"Accept": "application/json"}

            headers["Authorization"] = "Bearer " + os.environ["ACCESS_TOKEN"]

            payload = json.loads(r'''{
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Monthly membership",
                "recurring": {
                  "enabled": 1,
                  "schedule_name": "Monthly fee",
                  "recurring_type": 3,
                  "amount": "25.50",
                  "start_date": "2030-01-10",
                  "day_of_debit": "FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=15"
                },
                "surcharge_config": []
              },
              "notify_email": false,
              "notify_sms": false
            }''')

            body = json.dumps(payload).encode("utf-8")

            headers["Content-Type"] = "application/json"


            request = urllib.request.Request(url, data=body, headers=headers,
            method="POST")

            with urllib.request.urlopen(request, timeout=30) as response:
                print(response.read().decode("utf-8"))
        - lang: Python
          label: New customer with a one-off subscription
          source: >
            import json

            import os

            import urllib.parse

            import urllib.request


            base_url = os.environ["BASE_URL"].rstrip("/")

            url = base_url + "/api/v2/subscription/create"

            headers = {"Accept": "application/json"}

            headers["Authorization"] = "Bearer " + os.environ["ACCESS_TOKEN"]

            payload = json.loads(r'''{
              "merchant_id": "48290713",
              "customer": {
                "firstName": "Emily",
                "lastName": "Carter",
                "emailAddress": "emily.carter@example.com",
                "mobilePhoneNumber": "0491570006",
                "addressLine1": "18 Paperbark Avenue",
                "addressSuburb": "Sydney",
                "addressState": "NSW",
                "addressPostCode": "2000"
              },
              "plan": {
                "plan_name": "One time fee",
                "one_off": {
                  "enabled": 1,
                  "schedule_name": "Initial fee",
                  "amount": "20.00",
                  "payment_date": "2030-01-15"
                }
              }
            }''')

            body = json.dumps(payload).encode("utf-8")

            headers["Content-Type"] = "application/json"


            request = urllib.request.Request(url, data=body, headers=headers,
            method="POST")

            with urllib.request.urlopen(request, timeout=30) as response:
                print(response.read().decode("utf-8"))
        - lang: Python
          label: Subscription from a template
          source: >
            import json

            import os

            import urllib.parse

            import urllib.request


            base_url = os.environ["BASE_URL"].rstrip("/")

            url = base_url + "/api/v2/subscription/create"

            headers = {"Accept": "application/json"}

            headers["Authorization"] = "Bearer " + os.environ["ACCESS_TOKEN"]

            payload = json.loads(r'''{
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "template_id": "TPL62038591",
                "start_date": "2030-01-10"
              }
            }''')

            body = json.dumps(payload).encode("utf-8")

            headers["Content-Type"] = "application/json"


            request = urllib.request.Request(url, data=body, headers=headers,
            method="POST")

            with urllib.request.urlopen(request, timeout=30) as response:
                print(response.read().decode("utf-8"))
        - lang: Python
          label: Initial By agreement schedule
          source: >
            import json

            import os

            import urllib.parse

            import urllib.request


            base_url = os.environ["BASE_URL"].rstrip("/")

            url = base_url + "/api/v2/subscription/create"

            headers = {"Accept": "application/json"}

            headers["Authorization"] = "Bearer " + os.environ["ACCESS_TOKEN"]

            payload = json.loads(r'''{
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Usage based DDR",
                "schedule": {
                  "type": 6,
                  "schedule_name": "First usage charge",
                  "amount": "10.00",
                  "start_date": "2030-01-15"
                }
              }
            }''')

            body = json.dumps(payload).encode("utf-8")

            headers["Content-Type"] = "application/json"


            request = urllib.request.Request(url, data=body, headers=headers,
            method="POST")

            with urllib.request.urlopen(request, timeout=30) as response:
                print(response.read().decode("utf-8"))
        - lang: Python
          label: 'Custom frequency: every ten days'
          source: >
            import json

            import os

            import urllib.parse

            import urllib.request


            base_url = os.environ["BASE_URL"].rstrip("/")

            url = base_url + "/api/v2/subscription/create"

            headers = {"Accept": "application/json"}

            headers["Authorization"] = "Bearer " + os.environ["ACCESS_TOKEN"]

            payload = json.loads(r'''{
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Every ten days",
                "recurring": {
                  "enabled": 1,
                  "schedule_name": "Ten-day membership fee",
                  "recurring_type": 3,
                  "amount": "25.50",
                  "start_date": "2030-01-10",
                  "day_of_debit": "FREQ=DAILY;INTERVAL=10",
                  "process_type": 12,
                  "custom_cycle_type": 1,
                  "custom_cycle": 10
                }
              }
            }''')

            body = json.dumps(payload).encode("utf-8")

            headers["Content-Type"] = "application/json"


            request = urllib.request.Request(url, data=body, headers=headers,
            method="POST")

            with urllib.request.urlopen(request, timeout=30) as response:
                print(response.read().decode("utf-8"))
        - lang: Python
          label: Quarterly frequency with a first debit anchor
          source: >
            import json

            import os

            import urllib.parse

            import urllib.request


            base_url = os.environ["BASE_URL"].rstrip("/")

            url = base_url + "/api/v2/subscription/create"

            headers = {"Accept": "application/json"}

            headers["Authorization"] = "Bearer " + os.environ["ACCESS_TOKEN"]

            payload = json.loads(r'''{
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Quarterly membership",
                "recurring": {
                  "enabled": 1,
                  "schedule_name": "Quarterly membership fee",
                  "recurring_type": 3,
                  "amount": "25.50",
                  "start_date": "2030-01-10",
                  "day_of_debit": "FREQ=MONTHLY;INTERVAL=3;BYMONTHDAY=15",
                  "day_of_debit_dtstart": "2030-02-15"
                }
              }
            }''')

            body = json.dumps(payload).encode("utf-8")

            headers["Content-Type"] = "application/json"


            request = urllib.request.Request(url, data=body, headers=headers,
            method="POST")

            with urllib.request.urlopen(request, timeout=30) as response:
                print(response.read().decode("utf-8"))
        - lang: JavaScript
          label: Manually defined recurring subscription
          source: |
            const env = (name) => {
              const value = process.env[name];
              if (!value) throw new Error(`Missing environment variable: ${name}`);
              return value;
            };
            const baseUrl = env("BASE_URL").replace(/\/+$/, "");
            const url = new URL(baseUrl + "/api/v2/subscription/create");
            const headers = { Accept: "application/json" };
            headers.Authorization = `Bearer ${env("ACCESS_TOKEN")}`;
            const payload = {
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Monthly membership",
                "recurring": {
                  "enabled": 1,
                  "schedule_name": "Monthly fee",
                  "recurring_type": 3,
                  "amount": "25.50",
                  "start_date": "2030-01-10",
                  "day_of_debit": "FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=15"
                },
                "surcharge_config": []
              },
              "notify_email": false,
              "notify_sms": false
            };
            const body = JSON.stringify(payload);
            headers["Content-Type"] = "application/json";

            const response = await fetch(url, {
              method: "POST",
              headers,
              body,
              signal: AbortSignal.timeout(30_000),
            });
            console.log(await response.text());
        - lang: JavaScript
          label: New customer with a one-off subscription
          source: |
            const env = (name) => {
              const value = process.env[name];
              if (!value) throw new Error(`Missing environment variable: ${name}`);
              return value;
            };
            const baseUrl = env("BASE_URL").replace(/\/+$/, "");
            const url = new URL(baseUrl + "/api/v2/subscription/create");
            const headers = { Accept: "application/json" };
            headers.Authorization = `Bearer ${env("ACCESS_TOKEN")}`;
            const payload = {
              "merchant_id": "48290713",
              "customer": {
                "firstName": "Emily",
                "lastName": "Carter",
                "emailAddress": "emily.carter@example.com",
                "mobilePhoneNumber": "0491570006",
                "addressLine1": "18 Paperbark Avenue",
                "addressSuburb": "Sydney",
                "addressState": "NSW",
                "addressPostCode": "2000"
              },
              "plan": {
                "plan_name": "One time fee",
                "one_off": {
                  "enabled": 1,
                  "schedule_name": "Initial fee",
                  "amount": "20.00",
                  "payment_date": "2030-01-15"
                }
              }
            };
            const body = JSON.stringify(payload);
            headers["Content-Type"] = "application/json";

            const response = await fetch(url, {
              method: "POST",
              headers,
              body,
              signal: AbortSignal.timeout(30_000),
            });
            console.log(await response.text());
        - lang: JavaScript
          label: Subscription from a template
          source: |
            const env = (name) => {
              const value = process.env[name];
              if (!value) throw new Error(`Missing environment variable: ${name}`);
              return value;
            };
            const baseUrl = env("BASE_URL").replace(/\/+$/, "");
            const url = new URL(baseUrl + "/api/v2/subscription/create");
            const headers = { Accept: "application/json" };
            headers.Authorization = `Bearer ${env("ACCESS_TOKEN")}`;
            const payload = {
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "template_id": "TPL62038591",
                "start_date": "2030-01-10"
              }
            };
            const body = JSON.stringify(payload);
            headers["Content-Type"] = "application/json";

            const response = await fetch(url, {
              method: "POST",
              headers,
              body,
              signal: AbortSignal.timeout(30_000),
            });
            console.log(await response.text());
        - lang: JavaScript
          label: Initial By agreement schedule
          source: |
            const env = (name) => {
              const value = process.env[name];
              if (!value) throw new Error(`Missing environment variable: ${name}`);
              return value;
            };
            const baseUrl = env("BASE_URL").replace(/\/+$/, "");
            const url = new URL(baseUrl + "/api/v2/subscription/create");
            const headers = { Accept: "application/json" };
            headers.Authorization = `Bearer ${env("ACCESS_TOKEN")}`;
            const payload = {
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Usage based DDR",
                "schedule": {
                  "type": 6,
                  "schedule_name": "First usage charge",
                  "amount": "10.00",
                  "start_date": "2030-01-15"
                }
              }
            };
            const body = JSON.stringify(payload);
            headers["Content-Type"] = "application/json";

            const response = await fetch(url, {
              method: "POST",
              headers,
              body,
              signal: AbortSignal.timeout(30_000),
            });
            console.log(await response.text());
        - lang: JavaScript
          label: 'Custom frequency: every ten days'
          source: |
            const env = (name) => {
              const value = process.env[name];
              if (!value) throw new Error(`Missing environment variable: ${name}`);
              return value;
            };
            const baseUrl = env("BASE_URL").replace(/\/+$/, "");
            const url = new URL(baseUrl + "/api/v2/subscription/create");
            const headers = { Accept: "application/json" };
            headers.Authorization = `Bearer ${env("ACCESS_TOKEN")}`;
            const payload = {
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Every ten days",
                "recurring": {
                  "enabled": 1,
                  "schedule_name": "Ten-day membership fee",
                  "recurring_type": 3,
                  "amount": "25.50",
                  "start_date": "2030-01-10",
                  "day_of_debit": "FREQ=DAILY;INTERVAL=10",
                  "process_type": 12,
                  "custom_cycle_type": 1,
                  "custom_cycle": 10
                }
              }
            };
            const body = JSON.stringify(payload);
            headers["Content-Type"] = "application/json";

            const response = await fetch(url, {
              method: "POST",
              headers,
              body,
              signal: AbortSignal.timeout(30_000),
            });
            console.log(await response.text());
        - lang: JavaScript
          label: Quarterly frequency with a first debit anchor
          source: |
            const env = (name) => {
              const value = process.env[name];
              if (!value) throw new Error(`Missing environment variable: ${name}`);
              return value;
            };
            const baseUrl = env("BASE_URL").replace(/\/+$/, "");
            const url = new URL(baseUrl + "/api/v2/subscription/create");
            const headers = { Accept: "application/json" };
            headers.Authorization = `Bearer ${env("ACCESS_TOKEN")}`;
            const payload = {
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Quarterly membership",
                "recurring": {
                  "enabled": 1,
                  "schedule_name": "Quarterly membership fee",
                  "recurring_type": 3,
                  "amount": "25.50",
                  "start_date": "2030-01-10",
                  "day_of_debit": "FREQ=MONTHLY;INTERVAL=3;BYMONTHDAY=15",
                  "day_of_debit_dtstart": "2030-02-15"
                }
              }
            };
            const body = JSON.stringify(payload);
            headers["Content-Type"] = "application/json";

            const response = await fetch(url, {
              method: "POST",
              headers,
              body,
              signal: AbortSignal.timeout(30_000),
            });
            console.log(await response.text());
        - lang: PHP
          label: Manually defined recurring subscription
          source: |
            <?php
            $env = static function (string $name): string {
                $value = getenv($name);
                if ($value === false || $value === '') {
                    throw new RuntimeException("Missing environment variable: " . $name);
                }
                return $value;
            };
            $baseUrl = rtrim($env('BASE_URL'), '/');
            $url = $baseUrl . "/api/v2/subscription/create";
            $headers = ['Accept: application/json'];
            $headers[] = 'Authorization: Bearer ' . $env('ACCESS_TOKEN');
            $body = <<<'JSON'
            {
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Monthly membership",
                "recurring": {
                  "enabled": 1,
                  "schedule_name": "Monthly fee",
                  "recurring_type": 3,
                  "amount": "25.50",
                  "start_date": "2030-01-10",
                  "day_of_debit": "FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=15"
                },
                "surcharge_config": []
              },
              "notify_email": false,
              "notify_sms": false
            }
            JSON;
            $headers[] = 'Content-Type: application/json';

            $curl = curl_init($url);
            curl_setopt_array($curl, [
                CURLOPT_CUSTOMREQUEST => "POST",
                CURLOPT_HTTPHEADER => $headers,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => 30,
                CURLOPT_POSTFIELDS => $body,
            ]);
            $response = curl_exec($curl);
            if ($response === false) {
                $error = curl_error($curl);
                curl_close($curl);
                throw new RuntimeException($error);
            }
            curl_close($curl);
            echo $response, PHP_EOL;
        - lang: PHP
          label: New customer with a one-off subscription
          source: |
            <?php
            $env = static function (string $name): string {
                $value = getenv($name);
                if ($value === false || $value === '') {
                    throw new RuntimeException("Missing environment variable: " . $name);
                }
                return $value;
            };
            $baseUrl = rtrim($env('BASE_URL'), '/');
            $url = $baseUrl . "/api/v2/subscription/create";
            $headers = ['Accept: application/json'];
            $headers[] = 'Authorization: Bearer ' . $env('ACCESS_TOKEN');
            $body = <<<'JSON'
            {
              "merchant_id": "48290713",
              "customer": {
                "firstName": "Emily",
                "lastName": "Carter",
                "emailAddress": "emily.carter@example.com",
                "mobilePhoneNumber": "0491570006",
                "addressLine1": "18 Paperbark Avenue",
                "addressSuburb": "Sydney",
                "addressState": "NSW",
                "addressPostCode": "2000"
              },
              "plan": {
                "plan_name": "One time fee",
                "one_off": {
                  "enabled": 1,
                  "schedule_name": "Initial fee",
                  "amount": "20.00",
                  "payment_date": "2030-01-15"
                }
              }
            }
            JSON;
            $headers[] = 'Content-Type: application/json';

            $curl = curl_init($url);
            curl_setopt_array($curl, [
                CURLOPT_CUSTOMREQUEST => "POST",
                CURLOPT_HTTPHEADER => $headers,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => 30,
                CURLOPT_POSTFIELDS => $body,
            ]);
            $response = curl_exec($curl);
            if ($response === false) {
                $error = curl_error($curl);
                curl_close($curl);
                throw new RuntimeException($error);
            }
            curl_close($curl);
            echo $response, PHP_EOL;
        - lang: PHP
          label: Subscription from a template
          source: |
            <?php
            $env = static function (string $name): string {
                $value = getenv($name);
                if ($value === false || $value === '') {
                    throw new RuntimeException("Missing environment variable: " . $name);
                }
                return $value;
            };
            $baseUrl = rtrim($env('BASE_URL'), '/');
            $url = $baseUrl . "/api/v2/subscription/create";
            $headers = ['Accept: application/json'];
            $headers[] = 'Authorization: Bearer ' . $env('ACCESS_TOKEN');
            $body = <<<'JSON'
            {
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "template_id": "TPL62038591",
                "start_date": "2030-01-10"
              }
            }
            JSON;
            $headers[] = 'Content-Type: application/json';

            $curl = curl_init($url);
            curl_setopt_array($curl, [
                CURLOPT_CUSTOMREQUEST => "POST",
                CURLOPT_HTTPHEADER => $headers,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => 30,
                CURLOPT_POSTFIELDS => $body,
            ]);
            $response = curl_exec($curl);
            if ($response === false) {
                $error = curl_error($curl);
                curl_close($curl);
                throw new RuntimeException($error);
            }
            curl_close($curl);
            echo $response, PHP_EOL;
        - lang: PHP
          label: Initial By agreement schedule
          source: |
            <?php
            $env = static function (string $name): string {
                $value = getenv($name);
                if ($value === false || $value === '') {
                    throw new RuntimeException("Missing environment variable: " . $name);
                }
                return $value;
            };
            $baseUrl = rtrim($env('BASE_URL'), '/');
            $url = $baseUrl . "/api/v2/subscription/create";
            $headers = ['Accept: application/json'];
            $headers[] = 'Authorization: Bearer ' . $env('ACCESS_TOKEN');
            $body = <<<'JSON'
            {
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Usage based DDR",
                "schedule": {
                  "type": 6,
                  "schedule_name": "First usage charge",
                  "amount": "10.00",
                  "start_date": "2030-01-15"
                }
              }
            }
            JSON;
            $headers[] = 'Content-Type: application/json';

            $curl = curl_init($url);
            curl_setopt_array($curl, [
                CURLOPT_CUSTOMREQUEST => "POST",
                CURLOPT_HTTPHEADER => $headers,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => 30,
                CURLOPT_POSTFIELDS => $body,
            ]);
            $response = curl_exec($curl);
            if ($response === false) {
                $error = curl_error($curl);
                curl_close($curl);
                throw new RuntimeException($error);
            }
            curl_close($curl);
            echo $response, PHP_EOL;
        - lang: PHP
          label: 'Custom frequency: every ten days'
          source: |
            <?php
            $env = static function (string $name): string {
                $value = getenv($name);
                if ($value === false || $value === '') {
                    throw new RuntimeException("Missing environment variable: " . $name);
                }
                return $value;
            };
            $baseUrl = rtrim($env('BASE_URL'), '/');
            $url = $baseUrl . "/api/v2/subscription/create";
            $headers = ['Accept: application/json'];
            $headers[] = 'Authorization: Bearer ' . $env('ACCESS_TOKEN');
            $body = <<<'JSON'
            {
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Every ten days",
                "recurring": {
                  "enabled": 1,
                  "schedule_name": "Ten-day membership fee",
                  "recurring_type": 3,
                  "amount": "25.50",
                  "start_date": "2030-01-10",
                  "day_of_debit": "FREQ=DAILY;INTERVAL=10",
                  "process_type": 12,
                  "custom_cycle_type": 1,
                  "custom_cycle": 10
                }
              }
            }
            JSON;
            $headers[] = 'Content-Type: application/json';

            $curl = curl_init($url);
            curl_setopt_array($curl, [
                CURLOPT_CUSTOMREQUEST => "POST",
                CURLOPT_HTTPHEADER => $headers,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => 30,
                CURLOPT_POSTFIELDS => $body,
            ]);
            $response = curl_exec($curl);
            if ($response === false) {
                $error = curl_error($curl);
                curl_close($curl);
                throw new RuntimeException($error);
            }
            curl_close($curl);
            echo $response, PHP_EOL;
        - lang: PHP
          label: Quarterly frequency with a first debit anchor
          source: |
            <?php
            $env = static function (string $name): string {
                $value = getenv($name);
                if ($value === false || $value === '') {
                    throw new RuntimeException("Missing environment variable: " . $name);
                }
                return $value;
            };
            $baseUrl = rtrim($env('BASE_URL'), '/');
            $url = $baseUrl . "/api/v2/subscription/create";
            $headers = ['Accept: application/json'];
            $headers[] = 'Authorization: Bearer ' . $env('ACCESS_TOKEN');
            $body = <<<'JSON'
            {
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Quarterly membership",
                "recurring": {
                  "enabled": 1,
                  "schedule_name": "Quarterly membership fee",
                  "recurring_type": 3,
                  "amount": "25.50",
                  "start_date": "2030-01-10",
                  "day_of_debit": "FREQ=MONTHLY;INTERVAL=3;BYMONTHDAY=15",
                  "day_of_debit_dtstart": "2030-02-15"
                }
              }
            }
            JSON;
            $headers[] = 'Content-Type: application/json';

            $curl = curl_init($url);
            curl_setopt_array($curl, [
                CURLOPT_CUSTOMREQUEST => "POST",
                CURLOPT_HTTPHEADER => $headers,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => 30,
                CURLOPT_POSTFIELDS => $body,
            ]);
            $response = curl_exec($curl);
            if ($response === false) {
                $error = curl_error($curl);
                curl_close($curl);
                throw new RuntimeException($error);
            }
            curl_close($curl);
            echo $response, PHP_EOL;
        - lang: Go
          label: Manually defined recurring subscription
          source: |
            package main

            import (
                "fmt"
                "io"
                "net/http"
                "os"
                "strings"
                "time"
            )

            func mustEnv(name string) string {
                value := os.Getenv(name)
                if value == "" { panic("Missing environment variable: " + name) }
                return value
            }

            func main() {
                baseURL := strings.TrimRight(mustEnv("BASE_URL"), "/")
                endpoint := baseURL + "/api/v2/subscription/create"
                payload := `{
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Monthly membership",
                "recurring": {
                  "enabled": 1,
                  "schedule_name": "Monthly fee",
                  "recurring_type": 3,
                  "amount": "25.50",
                  "start_date": "2030-01-10",
                  "day_of_debit": "FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=15"
                },
                "surcharge_config": []
              },
              "notify_email": false,
              "notify_sms": false
            }`
                body := strings.NewReader(payload)
                req, err := http.NewRequest("POST", endpoint, body)
                if err != nil { panic(err) }
                req.Header.Set("Accept", "application/json")
                req.Header.Set("Authorization", "Bearer " + mustEnv("ACCESS_TOKEN"))
                req.Header.Set("Content-Type", "application/json")
                client := &http.Client{Timeout: 30 * time.Second}
                response, err := client.Do(req)
                if err != nil { panic(err) }
                defer response.Body.Close()
                result, err := io.ReadAll(response.Body)
                if err != nil { panic(err) }
                fmt.Println(string(result))
            }
        - lang: Go
          label: New customer with a one-off subscription
          source: |
            package main

            import (
                "fmt"
                "io"
                "net/http"
                "os"
                "strings"
                "time"
            )

            func mustEnv(name string) string {
                value := os.Getenv(name)
                if value == "" { panic("Missing environment variable: " + name) }
                return value
            }

            func main() {
                baseURL := strings.TrimRight(mustEnv("BASE_URL"), "/")
                endpoint := baseURL + "/api/v2/subscription/create"
                payload := `{
              "merchant_id": "48290713",
              "customer": {
                "firstName": "Emily",
                "lastName": "Carter",
                "emailAddress": "emily.carter@example.com",
                "mobilePhoneNumber": "0491570006",
                "addressLine1": "18 Paperbark Avenue",
                "addressSuburb": "Sydney",
                "addressState": "NSW",
                "addressPostCode": "2000"
              },
              "plan": {
                "plan_name": "One time fee",
                "one_off": {
                  "enabled": 1,
                  "schedule_name": "Initial fee",
                  "amount": "20.00",
                  "payment_date": "2030-01-15"
                }
              }
            }`
                body := strings.NewReader(payload)
                req, err := http.NewRequest("POST", endpoint, body)
                if err != nil { panic(err) }
                req.Header.Set("Accept", "application/json")
                req.Header.Set("Authorization", "Bearer " + mustEnv("ACCESS_TOKEN"))
                req.Header.Set("Content-Type", "application/json")
                client := &http.Client{Timeout: 30 * time.Second}
                response, err := client.Do(req)
                if err != nil { panic(err) }
                defer response.Body.Close()
                result, err := io.ReadAll(response.Body)
                if err != nil { panic(err) }
                fmt.Println(string(result))
            }
        - lang: Go
          label: Subscription from a template
          source: |
            package main

            import (
                "fmt"
                "io"
                "net/http"
                "os"
                "strings"
                "time"
            )

            func mustEnv(name string) string {
                value := os.Getenv(name)
                if value == "" { panic("Missing environment variable: " + name) }
                return value
            }

            func main() {
                baseURL := strings.TrimRight(mustEnv("BASE_URL"), "/")
                endpoint := baseURL + "/api/v2/subscription/create"
                payload := `{
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "template_id": "TPL62038591",
                "start_date": "2030-01-10"
              }
            }`
                body := strings.NewReader(payload)
                req, err := http.NewRequest("POST", endpoint, body)
                if err != nil { panic(err) }
                req.Header.Set("Accept", "application/json")
                req.Header.Set("Authorization", "Bearer " + mustEnv("ACCESS_TOKEN"))
                req.Header.Set("Content-Type", "application/json")
                client := &http.Client{Timeout: 30 * time.Second}
                response, err := client.Do(req)
                if err != nil { panic(err) }
                defer response.Body.Close()
                result, err := io.ReadAll(response.Body)
                if err != nil { panic(err) }
                fmt.Println(string(result))
            }
        - lang: Go
          label: Initial By agreement schedule
          source: |
            package main

            import (
                "fmt"
                "io"
                "net/http"
                "os"
                "strings"
                "time"
            )

            func mustEnv(name string) string {
                value := os.Getenv(name)
                if value == "" { panic("Missing environment variable: " + name) }
                return value
            }

            func main() {
                baseURL := strings.TrimRight(mustEnv("BASE_URL"), "/")
                endpoint := baseURL + "/api/v2/subscription/create"
                payload := `{
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Usage based DDR",
                "schedule": {
                  "type": 6,
                  "schedule_name": "First usage charge",
                  "amount": "10.00",
                  "start_date": "2030-01-15"
                }
              }
            }`
                body := strings.NewReader(payload)
                req, err := http.NewRequest("POST", endpoint, body)
                if err != nil { panic(err) }
                req.Header.Set("Accept", "application/json")
                req.Header.Set("Authorization", "Bearer " + mustEnv("ACCESS_TOKEN"))
                req.Header.Set("Content-Type", "application/json")
                client := &http.Client{Timeout: 30 * time.Second}
                response, err := client.Do(req)
                if err != nil { panic(err) }
                defer response.Body.Close()
                result, err := io.ReadAll(response.Body)
                if err != nil { panic(err) }
                fmt.Println(string(result))
            }
        - lang: Go
          label: 'Custom frequency: every ten days'
          source: |
            package main

            import (
                "fmt"
                "io"
                "net/http"
                "os"
                "strings"
                "time"
            )

            func mustEnv(name string) string {
                value := os.Getenv(name)
                if value == "" { panic("Missing environment variable: " + name) }
                return value
            }

            func main() {
                baseURL := strings.TrimRight(mustEnv("BASE_URL"), "/")
                endpoint := baseURL + "/api/v2/subscription/create"
                payload := `{
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Every ten days",
                "recurring": {
                  "enabled": 1,
                  "schedule_name": "Ten-day membership fee",
                  "recurring_type": 3,
                  "amount": "25.50",
                  "start_date": "2030-01-10",
                  "day_of_debit": "FREQ=DAILY;INTERVAL=10",
                  "process_type": 12,
                  "custom_cycle_type": 1,
                  "custom_cycle": 10
                }
              }
            }`
                body := strings.NewReader(payload)
                req, err := http.NewRequest("POST", endpoint, body)
                if err != nil { panic(err) }
                req.Header.Set("Accept", "application/json")
                req.Header.Set("Authorization", "Bearer " + mustEnv("ACCESS_TOKEN"))
                req.Header.Set("Content-Type", "application/json")
                client := &http.Client{Timeout: 30 * time.Second}
                response, err := client.Do(req)
                if err != nil { panic(err) }
                defer response.Body.Close()
                result, err := io.ReadAll(response.Body)
                if err != nil { panic(err) }
                fmt.Println(string(result))
            }
        - lang: Go
          label: Quarterly frequency with a first debit anchor
          source: |
            package main

            import (
                "fmt"
                "io"
                "net/http"
                "os"
                "strings"
                "time"
            )

            func mustEnv(name string) string {
                value := os.Getenv(name)
                if value == "" { panic("Missing environment variable: " + name) }
                return value
            }

            func main() {
                baseURL := strings.TrimRight(mustEnv("BASE_URL"), "/")
                endpoint := baseURL + "/api/v2/subscription/create"
                payload := `{
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Quarterly membership",
                "recurring": {
                  "enabled": 1,
                  "schedule_name": "Quarterly membership fee",
                  "recurring_type": 3,
                  "amount": "25.50",
                  "start_date": "2030-01-10",
                  "day_of_debit": "FREQ=MONTHLY;INTERVAL=3;BYMONTHDAY=15",
                  "day_of_debit_dtstart": "2030-02-15"
                }
              }
            }`
                body := strings.NewReader(payload)
                req, err := http.NewRequest("POST", endpoint, body)
                if err != nil { panic(err) }
                req.Header.Set("Accept", "application/json")
                req.Header.Set("Authorization", "Bearer " + mustEnv("ACCESS_TOKEN"))
                req.Header.Set("Content-Type", "application/json")
                client := &http.Client{Timeout: 30 * time.Second}
                response, err := client.Do(req)
                if err != nil { panic(err) }
                defer response.Body.Close()
                result, err := io.ReadAll(response.Body)
                if err != nil { panic(err) }
                fmt.Println(string(result))
            }
        - lang: Java
          label: Manually defined recurring subscription
          source: |
            import java.io.ByteArrayOutputStream;
            import java.net.URI;
            import java.net.URLEncoder;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;
            import java.nio.charset.StandardCharsets;
            import java.nio.file.Files;
            import java.nio.file.Path;
            import java.time.Duration;
            import java.util.LinkedHashMap;
            import java.util.Map;
            import java.util.UUID;
            import java.util.stream.Collectors;

            public class Example {
                static String requireEnv(String name) {
                    String value = System.getenv(name);
                    if (value == null || value.isEmpty()) {
                        throw new IllegalArgumentException("Missing environment variable: " + name);
                    }
                    return value;
                }

                public static void main(String[] args) throws Exception {
                    String baseUrl = requireEnv("BASE_URL").replaceAll("/+$", "");
                    String endpoint = baseUrl + "/api/v2/subscription/create";
                    String payload =
                        "{\n" +
                        "  \"merchant_id\": \"48290713\",\n" +
                        "  \"customer\": {\n" +
                        "    \"customer_id\": \"CUS48290713\"\n" +
                        "  },\n" +
                        "  \"plan\": {\n" +
                        "    \"plan_name\": \"Monthly membership\",\n" +
                        "    \"recurring\": {\n" +
                        "      \"enabled\": 1,\n" +
                        "      \"schedule_name\": \"Monthly fee\",\n" +
                        "      \"recurring_type\": 3,\n" +
                        "      \"amount\": \"25.50\",\n" +
                        "      \"start_date\": \"2030-01-10\",\n" +
                        "      \"day_of_debit\": \"FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=15\"\n" +
                        "    },\n" +
                        "    \"surcharge_config\": []\n" +
                        "  },\n" +
                        "  \"notify_email\": false,\n" +
                        "  \"notify_sms\": false\n" +
                        "}";
                    HttpRequest.Builder builder = HttpRequest.newBuilder(URI.create(endpoint))
                        .timeout(Duration.ofSeconds(30))
                        .header("Accept", "application/json");
                    builder.header("Authorization", "Bearer " + requireEnv("ACCESS_TOKEN"));
                    builder.header("Content-Type", "application/json");
                    HttpRequest request = builder.method("POST", HttpRequest.BodyPublishers.ofString(payload, StandardCharsets.UTF_8)).build();
                    HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build();
                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
                    System.out.println(response.body());
                }
            }
        - lang: Java
          label: New customer with a one-off subscription
          source: |
            import java.io.ByteArrayOutputStream;
            import java.net.URI;
            import java.net.URLEncoder;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;
            import java.nio.charset.StandardCharsets;
            import java.nio.file.Files;
            import java.nio.file.Path;
            import java.time.Duration;
            import java.util.LinkedHashMap;
            import java.util.Map;
            import java.util.UUID;
            import java.util.stream.Collectors;

            public class Example {
                static String requireEnv(String name) {
                    String value = System.getenv(name);
                    if (value == null || value.isEmpty()) {
                        throw new IllegalArgumentException("Missing environment variable: " + name);
                    }
                    return value;
                }

                public static void main(String[] args) throws Exception {
                    String baseUrl = requireEnv("BASE_URL").replaceAll("/+$", "");
                    String endpoint = baseUrl + "/api/v2/subscription/create";
                    String payload =
                        "{\n" +
                        "  \"merchant_id\": \"48290713\",\n" +
                        "  \"customer\": {\n" +
                        "    \"firstName\": \"Emily\",\n" +
                        "    \"lastName\": \"Carter\",\n" +
                        "    \"emailAddress\": \"emily.carter@example.com\",\n" +
                        "    \"mobilePhoneNumber\": \"0491570006\",\n" +
                        "    \"addressLine1\": \"18 Paperbark Avenue\",\n" +
                        "    \"addressSuburb\": \"Sydney\",\n" +
                        "    \"addressState\": \"NSW\",\n" +
                        "    \"addressPostCode\": \"2000\"\n" +
                        "  },\n" +
                        "  \"plan\": {\n" +
                        "    \"plan_name\": \"One time fee\",\n" +
                        "    \"one_off\": {\n" +
                        "      \"enabled\": 1,\n" +
                        "      \"schedule_name\": \"Initial fee\",\n" +
                        "      \"amount\": \"20.00\",\n" +
                        "      \"payment_date\": \"2030-01-15\"\n" +
                        "    }\n" +
                        "  }\n" +
                        "}";
                    HttpRequest.Builder builder = HttpRequest.newBuilder(URI.create(endpoint))
                        .timeout(Duration.ofSeconds(30))
                        .header("Accept", "application/json");
                    builder.header("Authorization", "Bearer " + requireEnv("ACCESS_TOKEN"));
                    builder.header("Content-Type", "application/json");
                    HttpRequest request = builder.method("POST", HttpRequest.BodyPublishers.ofString(payload, StandardCharsets.UTF_8)).build();
                    HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build();
                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
                    System.out.println(response.body());
                }
            }
        - lang: Java
          label: Subscription from a template
          source: |
            import java.io.ByteArrayOutputStream;
            import java.net.URI;
            import java.net.URLEncoder;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;
            import java.nio.charset.StandardCharsets;
            import java.nio.file.Files;
            import java.nio.file.Path;
            import java.time.Duration;
            import java.util.LinkedHashMap;
            import java.util.Map;
            import java.util.UUID;
            import java.util.stream.Collectors;

            public class Example {
                static String requireEnv(String name) {
                    String value = System.getenv(name);
                    if (value == null || value.isEmpty()) {
                        throw new IllegalArgumentException("Missing environment variable: " + name);
                    }
                    return value;
                }

                public static void main(String[] args) throws Exception {
                    String baseUrl = requireEnv("BASE_URL").replaceAll("/+$", "");
                    String endpoint = baseUrl + "/api/v2/subscription/create";
                    String payload =
                        "{\n" +
                        "  \"merchant_id\": \"48290713\",\n" +
                        "  \"customer\": {\n" +
                        "    \"customer_id\": \"CUS48290713\"\n" +
                        "  },\n" +
                        "  \"plan\": {\n" +
                        "    \"template_id\": \"TPL62038591\",\n" +
                        "    \"start_date\": \"2030-01-10\"\n" +
                        "  }\n" +
                        "}";
                    HttpRequest.Builder builder = HttpRequest.newBuilder(URI.create(endpoint))
                        .timeout(Duration.ofSeconds(30))
                        .header("Accept", "application/json");
                    builder.header("Authorization", "Bearer " + requireEnv("ACCESS_TOKEN"));
                    builder.header("Content-Type", "application/json");
                    HttpRequest request = builder.method("POST", HttpRequest.BodyPublishers.ofString(payload, StandardCharsets.UTF_8)).build();
                    HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build();
                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
                    System.out.println(response.body());
                }
            }
        - lang: Java
          label: Initial By agreement schedule
          source: |
            import java.io.ByteArrayOutputStream;
            import java.net.URI;
            import java.net.URLEncoder;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;
            import java.nio.charset.StandardCharsets;
            import java.nio.file.Files;
            import java.nio.file.Path;
            import java.time.Duration;
            import java.util.LinkedHashMap;
            import java.util.Map;
            import java.util.UUID;
            import java.util.stream.Collectors;

            public class Example {
                static String requireEnv(String name) {
                    String value = System.getenv(name);
                    if (value == null || value.isEmpty()) {
                        throw new IllegalArgumentException("Missing environment variable: " + name);
                    }
                    return value;
                }

                public static void main(String[] args) throws Exception {
                    String baseUrl = requireEnv("BASE_URL").replaceAll("/+$", "");
                    String endpoint = baseUrl + "/api/v2/subscription/create";
                    String payload =
                        "{\n" +
                        "  \"merchant_id\": \"48290713\",\n" +
                        "  \"customer\": {\n" +
                        "    \"customer_id\": \"CUS48290713\"\n" +
                        "  },\n" +
                        "  \"plan\": {\n" +
                        "    \"plan_name\": \"Usage based DDR\",\n" +
                        "    \"schedule\": {\n" +
                        "      \"type\": 6,\n" +
                        "      \"schedule_name\": \"First usage charge\",\n" +
                        "      \"amount\": \"10.00\",\n" +
                        "      \"start_date\": \"2030-01-15\"\n" +
                        "    }\n" +
                        "  }\n" +
                        "}";
                    HttpRequest.Builder builder = HttpRequest.newBuilder(URI.create(endpoint))
                        .timeout(Duration.ofSeconds(30))
                        .header("Accept", "application/json");
                    builder.header("Authorization", "Bearer " + requireEnv("ACCESS_TOKEN"));
                    builder.header("Content-Type", "application/json");
                    HttpRequest request = builder.method("POST", HttpRequest.BodyPublishers.ofString(payload, StandardCharsets.UTF_8)).build();
                    HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build();
                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
                    System.out.println(response.body());
                }
            }
        - lang: Java
          label: 'Custom frequency: every ten days'
          source: |
            import java.io.ByteArrayOutputStream;
            import java.net.URI;
            import java.net.URLEncoder;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;
            import java.nio.charset.StandardCharsets;
            import java.nio.file.Files;
            import java.nio.file.Path;
            import java.time.Duration;
            import java.util.LinkedHashMap;
            import java.util.Map;
            import java.util.UUID;
            import java.util.stream.Collectors;

            public class Example {
                static String requireEnv(String name) {
                    String value = System.getenv(name);
                    if (value == null || value.isEmpty()) {
                        throw new IllegalArgumentException("Missing environment variable: " + name);
                    }
                    return value;
                }

                public static void main(String[] args) throws Exception {
                    String baseUrl = requireEnv("BASE_URL").replaceAll("/+$", "");
                    String endpoint = baseUrl + "/api/v2/subscription/create";
                    String payload =
                        "{\n" +
                        "  \"merchant_id\": \"48290713\",\n" +
                        "  \"customer\": {\n" +
                        "    \"customer_id\": \"CUS48290713\"\n" +
                        "  },\n" +
                        "  \"plan\": {\n" +
                        "    \"plan_name\": \"Every ten days\",\n" +
                        "    \"recurring\": {\n" +
                        "      \"enabled\": 1,\n" +
                        "      \"schedule_name\": \"Ten-day membership fee\",\n" +
                        "      \"recurring_type\": 3,\n" +
                        "      \"amount\": \"25.50\",\n" +
                        "      \"start_date\": \"2030-01-10\",\n" +
                        "      \"day_of_debit\": \"FREQ=DAILY;INTERVAL=10\",\n" +
                        "      \"process_type\": 12,\n" +
                        "      \"custom_cycle_type\": 1,\n" +
                        "      \"custom_cycle\": 10\n" +
                        "    }\n" +
                        "  }\n" +
                        "}";
                    HttpRequest.Builder builder = HttpRequest.newBuilder(URI.create(endpoint))
                        .timeout(Duration.ofSeconds(30))
                        .header("Accept", "application/json");
                    builder.header("Authorization", "Bearer " + requireEnv("ACCESS_TOKEN"));
                    builder.header("Content-Type", "application/json");
                    HttpRequest request = builder.method("POST", HttpRequest.BodyPublishers.ofString(payload, StandardCharsets.UTF_8)).build();
                    HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build();
                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
                    System.out.println(response.body());
                }
            }
        - lang: Java
          label: Quarterly frequency with a first debit anchor
          source: |
            import java.io.ByteArrayOutputStream;
            import java.net.URI;
            import java.net.URLEncoder;
            import java.net.http.HttpClient;
            import java.net.http.HttpRequest;
            import java.net.http.HttpResponse;
            import java.nio.charset.StandardCharsets;
            import java.nio.file.Files;
            import java.nio.file.Path;
            import java.time.Duration;
            import java.util.LinkedHashMap;
            import java.util.Map;
            import java.util.UUID;
            import java.util.stream.Collectors;

            public class Example {
                static String requireEnv(String name) {
                    String value = System.getenv(name);
                    if (value == null || value.isEmpty()) {
                        throw new IllegalArgumentException("Missing environment variable: " + name);
                    }
                    return value;
                }

                public static void main(String[] args) throws Exception {
                    String baseUrl = requireEnv("BASE_URL").replaceAll("/+$", "");
                    String endpoint = baseUrl + "/api/v2/subscription/create";
                    String payload =
                        "{\n" +
                        "  \"merchant_id\": \"48290713\",\n" +
                        "  \"customer\": {\n" +
                        "    \"customer_id\": \"CUS48290713\"\n" +
                        "  },\n" +
                        "  \"plan\": {\n" +
                        "    \"plan_name\": \"Quarterly membership\",\n" +
                        "    \"recurring\": {\n" +
                        "      \"enabled\": 1,\n" +
                        "      \"schedule_name\": \"Quarterly membership fee\",\n" +
                        "      \"recurring_type\": 3,\n" +
                        "      \"amount\": \"25.50\",\n" +
                        "      \"start_date\": \"2030-01-10\",\n" +
                        "      \"day_of_debit\": \"FREQ=MONTHLY;INTERVAL=3;BYMONTHDAY=15\",\n" +
                        "      \"day_of_debit_dtstart\": \"2030-02-15\"\n" +
                        "    }\n" +
                        "  }\n" +
                        "}";
                    HttpRequest.Builder builder = HttpRequest.newBuilder(URI.create(endpoint))
                        .timeout(Duration.ofSeconds(30))
                        .header("Accept", "application/json");
                    builder.header("Authorization", "Bearer " + requireEnv("ACCESS_TOKEN"));
                    builder.header("Content-Type", "application/json");
                    HttpRequest request = builder.method("POST", HttpRequest.BodyPublishers.ofString(payload, StandardCharsets.UTF_8)).build();
                    HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build();
                    HttpResponse<String> response = client.send(request,
                        HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
                    System.out.println(response.body());
                }
            }
        - lang: Ruby
          label: Manually defined recurring subscription
          source: |
            require "net/http"
            require "uri"

            base_url = ENV.fetch("BASE_URL").sub(%r{/+$}, "")
            uri = URI(base_url + "/api/v2/subscription/create")
            request = Net::HTTP::Post.new(uri)
            request["Accept"] = "application/json"
            request["Authorization"] = "Bearer " + ENV.fetch("ACCESS_TOKEN")
            request["Content-Type"] = "application/json"
            request.body = <<~'JSON'
            {
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Monthly membership",
                "recurring": {
                  "enabled": 1,
                  "schedule_name": "Monthly fee",
                  "recurring_type": 3,
                  "amount": "25.50",
                  "start_date": "2030-01-10",
                  "day_of_debit": "FREQ=MONTHLY;INTERVAL=1;BYMONTHDAY=15"
                },
                "surcharge_config": []
              },
              "notify_email": false,
              "notify_sms": false
            }
            JSON
            http = Net::HTTP.new(uri.host, uri.port)
            http.use_ssl = uri.scheme == "https"
            http.open_timeout = 30
            http.read_timeout = 30
            puts http.request(request).body
        - lang: Ruby
          label: New customer with a one-off subscription
          source: |
            require "net/http"
            require "uri"

            base_url = ENV.fetch("BASE_URL").sub(%r{/+$}, "")
            uri = URI(base_url + "/api/v2/subscription/create")
            request = Net::HTTP::Post.new(uri)
            request["Accept"] = "application/json"
            request["Authorization"] = "Bearer " + ENV.fetch("ACCESS_TOKEN")
            request["Content-Type"] = "application/json"
            request.body = <<~'JSON'
            {
              "merchant_id": "48290713",
              "customer": {
                "firstName": "Emily",
                "lastName": "Carter",
                "emailAddress": "emily.carter@example.com",
                "mobilePhoneNumber": "0491570006",
                "addressLine1": "18 Paperbark Avenue",
                "addressSuburb": "Sydney",
                "addressState": "NSW",
                "addressPostCode": "2000"
              },
              "plan": {
                "plan_name": "One time fee",
                "one_off": {
                  "enabled": 1,
                  "schedule_name": "Initial fee",
                  "amount": "20.00",
                  "payment_date": "2030-01-15"
                }
              }
            }
            JSON
            http = Net::HTTP.new(uri.host, uri.port)
            http.use_ssl = uri.scheme == "https"
            http.open_timeout = 30
            http.read_timeout = 30
            puts http.request(request).body
        - lang: Ruby
          label: Subscription from a template
          source: |
            require "net/http"
            require "uri"

            base_url = ENV.fetch("BASE_URL").sub(%r{/+$}, "")
            uri = URI(base_url + "/api/v2/subscription/create")
            request = Net::HTTP::Post.new(uri)
            request["Accept"] = "application/json"
            request["Authorization"] = "Bearer " + ENV.fetch("ACCESS_TOKEN")
            request["Content-Type"] = "application/json"
            request.body = <<~'JSON'
            {
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "template_id": "TPL62038591",
                "start_date": "2030-01-10"
              }
            }
            JSON
            http = Net::HTTP.new(uri.host, uri.port)
            http.use_ssl = uri.scheme == "https"
            http.open_timeout = 30
            http.read_timeout = 30
            puts http.request(request).body
        - lang: Ruby
          label: Initial By agreement schedule
          source: |
            require "net/http"
            require "uri"

            base_url = ENV.fetch("BASE_URL").sub(%r{/+$}, "")
            uri = URI(base_url + "/api/v2/subscription/create")
            request = Net::HTTP::Post.new(uri)
            request["Accept"] = "application/json"
            request["Authorization"] = "Bearer " + ENV.fetch("ACCESS_TOKEN")
            request["Content-Type"] = "application/json"
            request.body = <<~'JSON'
            {
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Usage based DDR",
                "schedule": {
                  "type": 6,
                  "schedule_name": "First usage charge",
                  "amount": "10.00",
                  "start_date": "2030-01-15"
                }
              }
            }
            JSON
            http = Net::HTTP.new(uri.host, uri.port)
            http.use_ssl = uri.scheme == "https"
            http.open_timeout = 30
            http.read_timeout = 30
            puts http.request(request).body
        - lang: Ruby
          label: 'Custom frequency: every ten days'
          source: |
            require "net/http"
            require "uri"

            base_url = ENV.fetch("BASE_URL").sub(%r{/+$}, "")
            uri = URI(base_url + "/api/v2/subscription/create")
            request = Net::HTTP::Post.new(uri)
            request["Accept"] = "application/json"
            request["Authorization"] = "Bearer " + ENV.fetch("ACCESS_TOKEN")
            request["Content-Type"] = "application/json"
            request.body = <<~'JSON'
            {
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Every ten days",
                "recurring": {
                  "enabled": 1,
                  "schedule_name": "Ten-day membership fee",
                  "recurring_type": 3,
                  "amount": "25.50",
                  "start_date": "2030-01-10",
                  "day_of_debit": "FREQ=DAILY;INTERVAL=10",
                  "process_type": 12,
                  "custom_cycle_type": 1,
                  "custom_cycle": 10
                }
              }
            }
            JSON
            http = Net::HTTP.new(uri.host, uri.port)
            http.use_ssl = uri.scheme == "https"
            http.open_timeout = 30
            http.read_timeout = 30
            puts http.request(request).body
        - lang: Ruby
          label: Quarterly frequency with a first debit anchor
          source: |
            require "net/http"
            require "uri"

            base_url = ENV.fetch("BASE_URL").sub(%r{/+$}, "")
            uri = URI(base_url + "/api/v2/subscription/create")
            request = Net::HTTP::Post.new(uri)
            request["Accept"] = "application/json"
            request["Authorization"] = "Bearer " + ENV.fetch("ACCESS_TOKEN")
            request["Content-Type"] = "application/json"
            request.body = <<~'JSON'
            {
              "merchant_id": "48290713",
              "customer": {
                "customer_id": "CUS48290713"
              },
              "plan": {
                "plan_name": "Quarterly membership",
                "recurring": {
                  "enabled": 1,
                  "schedule_name": "Quarterly membership fee",
                  "recurring_type": 3,
                  "amount": "25.50",
                  "start_date": "2030-01-10",
                  "day_of_debit": "FREQ=MONTHLY;INTERVAL=3;BYMONTHDAY=15",
                  "day_of_debit_dtstart": "2030-02-15"
                }
              }
            }
            JSON
            http = Net::HTTP.new(uri.host, uri.port)
            http.use_ssl = uri.scheme == "https"
            http.open_timeout = 30
            http.read_timeout = 30
            puts http.request(request).body
components:
  schemas:
    SubscriptionCreateRequest:
      type: object
      description: >-
        Creates a subscription awaiting activation. Supply either an existing
        customer reference or new customer details. New customers require
        firstName, lastName and emailAddress in full. Exactly one subscription
        definition mode is required: manual, template or By agreement. Manual
        mode must enable at least one charge segment. plan_name is required
        outside template mode. The nested customer and plan format is
        recommended.
      properties:
        merchant_id:
          type: string
          description: Business identifier assigned by BillBuddy.
          maxLength: 20
          minLength: 1
        notify_email:
          description: >-
            Whether to allow email notifications for this transaction or
            subscription. false prohibits them; true allows them. Omission or
            null uses the business's API email notification setting, which
            defaults to off. Actual delivery depends on notification preferences
            and applicable rules. Also accepts 0/1 and the strings "0"/"1".
          nullable: true
          oneOf:
            - type: boolean
              nullable: true
            - type: integer
              enum:
                - 0
                - 1
            - type: string
              enum:
                - '0'
                - '1'
        notify_sms:
          description: >-
            Whether to allow SMS notifications for this transaction or
            subscription. false prohibits them; true allows them. Omission or
            null uses the business's API SMS notification setting, which
            defaults to off. Actual delivery depends on notification preferences
            and applicable rules. Also accepts 0/1 and the strings "0"/"1".
          nullable: true
          oneOf:
            - type: boolean
              nullable: true
            - type: integer
              enum:
                - 0
                - 1
            - type: string
              enum:
                - '0'
                - '1'
        customer:
          type: object
          description: >-
            Supply customer_id to reuse a customer, or firstName, lastName and
            emailAddress to create one. These options are mutually exclusive.
          properties:
            customer_id:
              type: string
              description: >-
                BillBuddy customer identifier. Must identify a valid customer
                within the current merchant and business.
              nullable: true
              maxLength: 32
            firstName:
              type: string
              description: >-
                New customer's first name. Required when creating a new
                customer.
              nullable: true
              maxLength: 100
            lastName:
              type: string
              description: New customer's last name. Required when creating a new customer.
              nullable: true
              maxLength: 100
            emailAddress:
              type: string
              description: >-
                New customer's primary email address. Required when creating a
                new customer. If it already belongs to a customer in the same
                merchant and business, supply that existing customer_id instead.
              nullable: true
              format: email
              maxLength: 500
            mobilePhoneNumber:
              type: string
              description: Customer mobile phone number.
              nullable: true
              maxLength: 20
            addressLine1:
              type: string
              description: Customer address line 1.
              nullable: true
              maxLength: 255
            addressSuburb:
              type: string
              description: Customer city or suburb.
              nullable: true
              maxLength: 100
            addressState:
              type: string
              description: Customer state or province.
              nullable: true
              maxLength: 100
            addressPostCode:
              type: string
              description: Customer postcode.
              nullable: true
              maxLength: 50
        plan:
          type: object
          description: >-
            Choose exactly one mode: manual recurring/one_off, template_id, or
            By agreement schedule.
          properties:
            plan_name:
              type: string
              description: >-
                Subscription name. In template mode, omission or null inherits
                the template name. Required and nonempty in other modes.
              maxLength: 255
              nullable: true
            description:
              type: string
              description: Description.
              nullable: true
              maxLength: 500
            recurring:
              type: object
              properties:
                enabled:
                  description: >-
                    Whether to enable this segment. Prefer integer 1 to enable
                    or 0 to disable; true/false and the strings "0"/"1" are also
                    accepted. Manual mode must enable at least one segment. When
                    enabled, provide all fields marked as required for the
                    segment.
                  nullable: true
                  oneOf:
                    - type: integer
                      enum:
                        - 0
                        - 1
                        - null
                      nullable: true
                    - type: boolean
                    - type: string
                      enum:
                        - '0'
                        - '1'
                schedule_name:
                  type: string
                  description: >-
                    Payment schedule name. Required and non-null when
                    recurring.enabled=1 (or true); at most 255 characters.
                  nullable: true
                  maxLength: 255
                recurring_type:
                  type: integer
                  description: >-
                    1 after a number of successful payments; 2 at a cumulative
                    amount; 3 until cancelled; 4 on an end date. Type 5 is not
                    allowed here; use plan.schedule for By agreement. Required
                    when recurring.enabled=true.
                  nullable: true
                  enum:
                    - 1
                    - 2
                    - 3
                    - 4
                    - null
                amount:
                  oneOf:
                    - type: number
                      multipleOf: 0.01
                      minimum: 0.01
                      maximum: 9999999.99
                      nullable: true
                    - type: string
                      pattern: ^\d+(\.\d{1,2})?$
                      allOf:
                        - pattern: >-
                            ^0*(?:[1-9]\d{0,6}(?:\.\d{1,2})?|0\.(?:0[1-9]|[1-9]\d?))$
                  description: >-
                    One-off or per-payment amount in major currency units, for
                    example 10.50 means AUD 10.50. At most two decimal places.
                    Numbers and numeric strings are accepted, with a minimum of
                    0.01 and maximum of 9999999.99; the same range applies to
                    both types. Required when recurring.enabled=true.
                  nullable: true
                start_date:
                  type: string
                  description: >-
                    Start date. Required and non-null when recurring.enabled=1
                    or recurring.enabled=true. YYYY-MM-DD is recommended. Must
                    be no earlier than tomorrow in the service business
                    timezone.
                  nullable: true
                  format: date
                end_date:
                  type: string
                  description: >-
                    End date, preferably YYYY-MM-DD. Required and non-null when
                    the recurring segment is enabled and recurring_type=4. When
                    supplied, cannot precede start_date in the same segment.
                  nullable: true
                  format: date
                end_terms:
                  type: integer
                  description: >-
                    Number of successful payments, an integer of at least 1.
                    Required and non-null when the recurring segment is enabled
                    and recurring_type=1.
                  nullable: true
                  minimum: 1
                total_amount:
                  oneOf:
                    - type: number
                      multipleOf: 0.01
                      minimum: 0.01
                      nullable: true
                    - type: string
                      pattern: ^\d+(\.\d{1,2})?$
                      allOf:
                        - pattern: >-
                            ^0*(?:[1-9]\d*(?:\.\d{1,2})?|0\.(?:0[1-9]|[1-9]\d?))$
                  description: >-
                    Target total amount in major currency units, with at most
                    two decimal places and a minimum of 0.01. Accepts a number
                    or numeric string. Required and non-null when the recurring
                    segment is enabled and recurring_type=2. When amount and
                    total_amount are both supplied in the same segment, amount
                    must not exceed total_amount.
                  nullable: true
                day_of_debit:
                  type: string
                  description: >-
                    RFC 5545 RRULE debit rule. Required and non-null when the
                    recurring segment is enabled. See the integration guide for
                    frequency syntax. Must not place a debit day before
                    start_date within the same cycle. Nonstandard intervals
                    require process_type=12 and custom_cycle_type/custom_cycle.
                  nullable: true
                  maxLength: 255
                process_type:
                  type: integer
                  description: >-
                    Provide 12 only for a custom frequency. Other frequencies
                    are inferred from the RRULE; omit this field for them.
                    Nonstandard RRULE intervals must use Custom.
                  nullable: true
                  enum:
                    - 12
                    - null
                custom_cycle_type:
                  type: integer
                  description: >-
                    Required for process_type=12: 1 days, 2 weeks, 3 months, 4
                    years. Must correspond to the RRULE FREQ. Non-Custom mode
                    prohibits nonempty custom cycle parameters. Required and
                    non-null when recurring.process_type=12.
                  nullable: true
                  enum:
                    - 1
                    - 2
                    - 3
                    - 4
                    - null
                custom_cycle:
                  type: integer
                  description: >-
                    Required for process_type=12. A positive integer equal to
                    the RRULE INTERVAL. Minimum 5 for days and 1 for other
                    units. Required and non-null when recurring.process_type=12.
                  nullable: true
                  minimum: 1
                day_of_debit_dtstart:
                  type: string
                  description: >-
                    First debit anchor. Required for quarterly, half-yearly and
                    yearly frequencies. YYYY-MM-DD is recommended; the date must
                    be strictly after the corresponding start_date and within
                    one billing cycle (3/6/12 months, clamped to month end).
                    MM-DD is also accepted if it is a valid month/day; the
                    full-date window restriction does not apply to that format.
                  nullable: true
                  pattern: ^(\d{4}-)?\d{2}-\d{2}$
              description: Recurring subscription definition.
              nullable: true
              not:
                anyOf:
                  - allOf:
                      - required:
                          - enabled
                        properties:
                          enabled:
                            enum:
                              - true
                              - 1
                              - '1'
                      - not:
                          required:
                            - schedule_name
                            - recurring_type
                            - amount
                            - start_date
                            - day_of_debit
                          properties:
                            schedule_name:
                              not:
                                enum:
                                  - null
                              minLength: 1
                            recurring_type:
                              not:
                                enum:
                                  - null
                            amount:
                              not:
                                enum:
                                  - null
                            start_date:
                              not:
                                enum:
                                  - null
                              minLength: 1
                            day_of_debit:
                              not:
                                enum:
                                  - null
                              minLength: 1
                  - allOf:
                      - required:
                          - enabled
                          - recurring_type
                        properties:
                          enabled:
                            enum:
                              - true
                              - 1
                              - '1'
                          recurring_type:
                            enum:
                              - 1
                      - not:
                          required:
                            - end_terms
                          properties:
                            end_terms:
                              not:
                                enum:
                                  - null
                  - allOf:
                      - required:
                          - enabled
                          - recurring_type
                        properties:
                          enabled:
                            enum:
                              - true
                              - 1
                              - '1'
                          recurring_type:
                            enum:
                              - 2
                      - not:
                          required:
                            - total_amount
                          properties:
                            total_amount:
                              not:
                                enum:
                                  - null
                  - allOf:
                      - required:
                          - enabled
                          - recurring_type
                        properties:
                          enabled:
                            enum:
                              - true
                              - 1
                              - '1'
                          recurring_type:
                            enum:
                              - 4
                      - not:
                          required:
                            - end_date
                          properties:
                            end_date:
                              not:
                                enum:
                                  - null
                              minLength: 1
                  - allOf:
                      - required:
                          - process_type
                        properties:
                          process_type:
                            enum:
                              - 12
                      - not:
                          required:
                            - custom_cycle_type
                            - custom_cycle
                          properties:
                            custom_cycle_type:
                              not:
                                enum:
                                  - null
                            custom_cycle:
                              not:
                                enum:
                                  - null
                  - allOf:
                      - required:
                          - process_type
                          - custom_cycle_type
                        properties:
                          process_type:
                            enum:
                              - 12
                          custom_cycle_type:
                            enum:
                              - 1
                      - not:
                          required:
                            - custom_cycle
                          properties:
                            custom_cycle:
                              not:
                                enum:
                                  - null
                              minimum: 5
                  - allOf:
                      - required:
                          - custom_cycle_type
                        properties:
                          custom_cycle_type:
                            not:
                              enum:
                                - null
                      - not:
                          required:
                            - process_type
                          properties:
                            process_type:
                              enum:
                                - 12
                  - allOf:
                      - required:
                          - custom_cycle
                        properties:
                          custom_cycle:
                            not:
                              enum:
                                - null
                      - not:
                          required:
                            - process_type
                          properties:
                            process_type:
                              enum:
                                - 12
            one_off:
              type: object
              properties:
                enabled:
                  description: >-
                    Whether to enable this segment. Prefer integer 1 to enable
                    or 0 to disable; true/false and the strings "0"/"1" are also
                    accepted. Manual mode must enable at least one segment. When
                    enabled, provide all fields marked as required for the
                    segment.
                  nullable: true
                  oneOf:
                    - type: integer
                      enum:
                        - 0
                        - 1
                        - null
                      nullable: true
                    - type: boolean
                    - type: string
                      enum:
                        - '0'
                        - '1'
                schedule_name:
                  type: string
                  description: >-
                    Payment schedule name. Required and non-null when
                    one_off.enabled=1.
                  nullable: true
                  maxLength: 255
                amount:
                  oneOf:
                    - type: number
                      multipleOf: 0.01
                      minimum: 0.01
                      maximum: 9999999.99
                      nullable: true
                    - type: string
                      pattern: ^\d+(\.\d{1,2})?$
                      allOf:
                        - pattern: >-
                            ^0*(?:[1-9]\d{0,6}(?:\.\d{1,2})?|0\.(?:0[1-9]|[1-9]\d?))$
                  description: >-
                    One-off or per-payment amount in major currency units, for
                    example 10.50 means AUD 10.50. At most two decimal places.
                    Numbers and numeric strings are accepted, with a minimum of
                    0.01 and maximum of 9999999.99; the same range applies to
                    both types. Required and non-null when one_off.enabled=1.
                  nullable: true
                description:
                  type: string
                  description: Description.
                  nullable: true
                  maxLength: 500
                payment_date:
                  type: string
                  description: >-
                    One-off debit date. Must be no earlier than tomorrow in the
                    service business timezone. Required and non-null when
                    one_off.enabled=1. YYYY-MM-DD is recommended. Cannot precede
                    tomorrow in the service business timezone.
                  nullable: true
                  format: date
              description: >-
                One-off payment definition. Acts as a Deposit when enabled with
                recurring, or as a One-off when used alone.
              nullable: true
              not:
                anyOf:
                  - allOf:
                      - required:
                          - enabled
                        properties:
                          enabled:
                            enum:
                              - true
                              - 1
                              - '1'
                      - not:
                          required:
                            - schedule_name
                            - amount
                            - payment_date
                          properties:
                            schedule_name:
                              not:
                                enum:
                                  - null
                              minLength: 1
                            amount:
                              not:
                                enum:
                                  - null
                            payment_date:
                              not:
                                enum:
                                  - null
                              minLength: 1
            schedule:
              type: object
              properties:
                type:
                  type: integer
                  description: >-
                    Initial By agreement schedule type: 1 after a number of
                    successful payments; 2 at a cumulative amount; 3 until
                    cancelled; 4 on an end date; 6 One-off. Types 5 and 7 are
                    not supported.
                  enum:
                    - 1
                    - 2
                    - 3
                    - 4
                    - 6
                amount:
                  oneOf:
                    - type: number
                      multipleOf: 0.01
                      minimum: 0.01
                      maximum: 9999999.99
                    - type: string
                      pattern: ^\d+(\.\d{1,2})?$
                      allOf:
                        - pattern: >-
                            ^0*(?:[1-9]\d{0,6}(?:\.\d{1,2})?|0\.(?:0[1-9]|[1-9]\d?))$
                  description: >-
                    One-off or per-payment amount in major currency units, for
                    example 10.50 means AUD 10.50. At most two decimal places.
                    Numbers and numeric strings are accepted, with a minimum of
                    0.01 and maximum of 9999999.99; the same range applies to
                    both types. Required and non-null when schedule is nonempty.
                start_date:
                  type: string
                  description: >-
                    Start date. Required and non-null when schedule is nonempty.
                    YYYY-MM-DD is recommended. Must be no earlier than tomorrow
                    in the service business timezone.
                  format: date
                  minLength: 1
                schedule_name:
                  type: string
                  description: >-
                    Payment schedule name. Required and non-null when schedule
                    is nonempty; at most 255 characters.
                  maxLength: 255
                  minLength: 1
                total_amount:
                  oneOf:
                    - type: number
                      multipleOf: 0.01
                      minimum: 0.01
                      nullable: true
                    - type: string
                      pattern: ^\d+(\.\d{1,2})?$
                      allOf:
                        - pattern: >-
                            ^0*(?:[1-9]\d*(?:\.\d{1,2})?|0\.(?:0[1-9]|[1-9]\d?))$
                  description: >-
                    Target total amount in major currency units, with at most
                    two decimal places and a minimum of 0.01. Accepts a number
                    or numeric string. Required and non-null when
                    schedule.type=2. When amount and total_amount are both
                    supplied in the same segment, amount must not exceed
                    total_amount.
                  nullable: true
                day_of_debit:
                  type: string
                  description: >-
                    RFC 5545 RRULE debit rule. Required and non-null for
                    schedule.type=1/2/3/4; optional for type=6 (one-off). Must
                    not place a debit day before start_date within the same
                    cycle. Nonstandard intervals require process_type=12 and
                    custom_cycle_type/custom_cycle.
                  nullable: true
                  maxLength: 255
                end_date:
                  type: string
                  description: >-
                    End date, preferably YYYY-MM-DD. Required and non-null when
                    schedule.type=4. When supplied, cannot precede start_date in
                    the same segment.
                  nullable: true
                  format: date
                end_terms:
                  type: integer
                  description: >-
                    Number of successful payments, an integer of at least 1.
                    Required and non-null when schedule.type=1.
                  nullable: true
                  minimum: 1
                day_of_debit_dtstart:
                  type: string
                  description: >-
                    First debit anchor. Required for quarterly, half-yearly and
                    yearly frequencies. YYYY-MM-DD is recommended; the date must
                    be strictly after the corresponding start_date and within
                    one billing cycle (3/6/12 months, clamped to month end).
                    MM-DD is also accepted if it is a valid month/day; the
                    full-date window restriction does not apply to that format.
                  nullable: true
                  pattern: ^(\d{4}-)?\d{2}-\d{2}$
                process_type:
                  type: integer
                  description: >-
                    Provide 12 only for a custom frequency. Other frequencies
                    are inferred from the RRULE; omit this field for them.
                    Nonstandard RRULE intervals must use Custom.
                  nullable: true
                  enum:
                    - 12
                    - null
                custom_cycle_type:
                  type: integer
                  description: >-
                    Required for process_type=12: 1 days, 2 weeks, 3 months, 4
                    years. Must correspond to the RRULE FREQ. Non-Custom mode
                    prohibits nonempty custom cycle parameters. Required and
                    non-null when schedule.process_type=12.
                  nullable: true
                  enum:
                    - 1
                    - 2
                    - 3
                    - 4
                    - null
                custom_cycle:
                  type: integer
                  description: >-
                    Required for process_type=12. A positive integer equal to
                    the RRULE INTERVAL. Minimum 5 for days and 1 for other
                    units. Required and non-null when schedule.process_type=12.
                  nullable: true
                  minimum: 1
              description: >-
                Initial By agreement payment schedule definition. Mutually
                exclusive with manual recurring/one_off mode and template_id
                mode.
              nullable: true
              required:
                - type
                - amount
                - start_date
                - schedule_name
              not:
                anyOf:
                  - allOf:
                      - required:
                          - type
                        properties:
                          type:
                            enum:
                              - 1
                      - not:
                          required:
                            - end_terms
                          properties:
                            end_terms:
                              not:
                                enum:
                                  - null
                  - allOf:
                      - required:
                          - type
                        properties:
                          type:
                            enum:
                              - 2
                      - not:
                          required:
                            - total_amount
                          properties:
                            total_amount:
                              not:
                                enum:
                                  - null
                  - allOf:
                      - required:
                          - type
                        properties:
                          type:
                            enum:
                              - 4
                      - not:
                          required:
                            - end_date
                          properties:
                            end_date:
                              not:
                                enum:
                                  - null
                              minLength: 1
                  - allOf:
                      - required:
                          - type
                        properties:
                          type:
                            enum:
                              - 1
                              - 2
                              - 3
                              - 4
                      - not:
                          required:
                            - day_of_debit
                          properties:
                            day_of_debit:
                              not:
                                enum:
                                  - null
                              minLength: 1
                  - allOf:
                      - required:
                          - process_type
                        properties:
                          process_type:
                            enum:
                              - 12
                      - not:
                          required:
                            - custom_cycle_type
                            - custom_cycle
                          properties:
                            custom_cycle_type:
                              not:
                                enum:
                                  - null
                            custom_cycle:
                              not:
                                enum:
                                  - null
                  - allOf:
                      - required:
                          - process_type
                          - custom_cycle_type
                        properties:
                          process_type:
                            enum:
                              - 12
                          custom_cycle_type:
                            enum:
                              - 1
                      - not:
                          required:
                            - custom_cycle
                          properties:
                            custom_cycle:
                              not:
                                enum:
                                  - null
                              minimum: 5
                  - allOf:
                      - required:
                          - custom_cycle_type
                        properties:
                          custom_cycle_type:
                            not:
                              enum:
                                - null
                      - not:
                          required:
                            - process_type
                          properties:
                            process_type:
                              enum:
                                - 12
                  - allOf:
                      - required:
                          - custom_cycle
                        properties:
                          custom_cycle:
                            not:
                              enum:
                                - null
                      - not:
                          required:
                            - process_type
                          properties:
                            process_type:
                              enum:
                                - 12
            surcharge_config:
              type: array
              description: >-
                Surcharge options, preferably an array of strings. See the
                schema and examples for allowed options. Omission, null or an
                empty array disables all options; non-array values are also
                treated as all disabled. Unknown options do not enable charges.
                credit_card_surcharge selects the credit card surcharge group.
                Actual charges depend on merchant business rules and payment
                method restrictions. Applies in manual mode. Template mode uses
                the template's surcharge options, which this field cannot
                override. By agreement schedule mode does not support this
                setting. Card surcharges remain subject to the applicable
                charging policy; if it prohibits them, selecting card options
                does not enable charges.
              nullable: true
              items:
                type: string
                description: Surcharge option.
                enum:
                  - direct_debit_surcharge
                  - visa_domestic_surcharge
                  - visa_international_surcharge
                  - mastercard_domestic_surcharge
                  - mastercard_international_surcharge
                  - amex_domestic_surcharge
                  - amex_international_surcharge
                  - credit_card_surcharge
            dishonour_fee_switch:
              description: >-
                Whether to charge a customer dishonour fee. Omission or null
                defaults to off. Enabling it requires an applicable positive fee
                configuration; the signed terms determine the actual amount.
                Also accepts 0/1 and the strings "0"/"1". Applies only to manual
                recurring/one_off mode. Template mode and By agreement schedule
                mode do not support this setting through this field.
              nullable: true
              oneOf:
                - type: boolean
                  nullable: true
                - type: integer
                  enum:
                    - 0
                    - 1
                - type: string
                  enum:
                    - '0'
                    - '1'
            template_id:
              type: string
              description: >-
                Available template ID from GET /api/v2/plan/list. Only enabled,
                ACTIVE, non-tiered templates other than By agreement are
                accepted.
              nullable: true
              maxLength: 20
            start_date:
              type: string
              description: >-
                Date override for the template's recurring segment. Required
                when the template contains recurring. Must be no earlier than
                tomorrow in the service business timezone.
              nullable: true
              format: date
            payment_date:
              type: string
              description: >-
                Date override for the template's one_off segment. Required when
                the template contains one_off. Must be no earlier than tomorrow
                in the service business timezone.
              nullable: true
              format: date
        customer_id:
          type: string
          description: >-
            Supported top-level alternative; use `customer.customer_id` for new
            integrations. If both forms supply this field, the nested value
            takes precedence.


            BillBuddy customer identifier. Must identify a valid customer within
            the current merchant and business.
          nullable: true
          maxLength: 32
        firstName:
          type: string
          description: >-
            Supported top-level alternative; use `customer.firstName` for new
            integrations. If both forms supply this field, the nested value
            takes precedence.


            New customer's first name. Required when creating a new customer.
          nullable: true
          maxLength: 100
        lastName:
          type: string
          description: >-
            Supported top-level alternative; use `customer.lastName` for new
            integrations. If both forms supply this field, the nested value
            takes precedence.


            New customer's last name. Required when creating a new customer.
          nullable: true
          maxLength: 100
        emailAddress:
          type: string
          description: >-
            Supported top-level alternative; use `customer.emailAddress` for new
            integrations. If both forms supply this field, the nested value
            takes precedence.


            New customer's primary email address. Required when creating a new
            customer. If it already belongs to a customer in the same merchant
            and business, supply that existing customer_id instead.
          nullable: true
          format: email
          maxLength: 500
        mobilePhoneNumber:
          type: string
          description: >-
            Supported top-level alternative; use `customer.mobilePhoneNumber`
            for new integrations. If both forms supply this field, the nested
            value takes precedence.


            Customer mobile phone number.
          nullable: true
          maxLength: 20
        addressLine1:
          type: string
          description: >-
            Supported top-level alternative; use `customer.addressLine1` for new
            integrations. If both forms supply this field, the nested value
            takes precedence.


            Customer address line 1.
          nullable: true
          maxLength: 255
        addressSuburb:
          type: string
          description: >-
            Supported top-level alternative; use `customer.addressSuburb` for
            new integrations. If both forms supply this field, the nested value
            takes precedence.


            Customer city or suburb.
          nullable: true
          maxLength: 100
        addressState:
          type: string
          description: >-
            Supported top-level alternative; use `customer.addressState` for new
            integrations. If both forms supply this field, the nested value
            takes precedence.


            Customer state or province.
          nullable: true
          maxLength: 100
        addressPostCode:
          type: string
          description: >-
            Supported top-level alternative; use `customer.addressPostCode` for
            new integrations. If both forms supply this field, the nested value
            takes precedence.


            Customer postcode.
          nullable: true
          maxLength: 50
        plan_name:
          type: string
          description: >-
            Supported top-level alternative; use `plan.plan_name` for new
            integrations. If both forms supply this field, the nested value
            takes precedence.


            Subscription name. In template mode, omission or null inherits the
            template name. Required and nonempty in other modes.
          maxLength: 255
          nullable: true
        description:
          type: string
          description: >-
            Supported top-level alternative; use `plan.description` for new
            integrations. If both forms supply this field, the nested value
            takes precedence.


            Description.
          nullable: true
          maxLength: 500
        recurring:
          type: object
          properties:
            enabled:
              description: >-
                Whether to enable this segment. Prefer integer 1 to enable or 0
                to disable; true/false and the strings "0"/"1" are also
                accepted. Manual mode must enable at least one segment. When
                enabled, provide all fields marked as required for the segment.
              nullable: true
              oneOf:
                - type: integer
                  enum:
                    - 0
                    - 1
                    - null
                  nullable: true
                - type: boolean
                - type: string
                  enum:
                    - '0'
                    - '1'
            schedule_name:
              type: string
              description: >-
                Payment schedule name. Required and non-null when
                recurring.enabled=1 (or true); at most 255 characters.
              nullable: true
              maxLength: 255
            recurring_type:
              type: integer
              description: >-
                1 after a number of successful payments; 2 at a cumulative
                amount; 3 until cancelled; 4 on an end date. Type 5 is not
                allowed here; use plan.schedule for By agreement. Required when
                recurring.enabled=true.
              nullable: true
              enum:
                - 1
                - 2
                - 3
                - 4
                - null
            amount:
              oneOf:
                - type: number
                  multipleOf: 0.01
                  minimum: 0.01
                  maximum: 9999999.99
                  nullable: true
                - type: string
                  pattern: ^\d+(\.\d{1,2})?$
                  allOf:
                    - pattern: >-
                        ^0*(?:[1-9]\d{0,6}(?:\.\d{1,2})?|0\.(?:0[1-9]|[1-9]\d?))$
              description: >-
                One-off or per-payment amount in major currency units, for
                example 10.50 means AUD 10.50. At most two decimal places.
                Numbers and numeric strings are accepted, with a minimum of 0.01
                and maximum of 9999999.99; the same range applies to both types.
                Required when recurring.enabled=true.
              nullable: true
            start_date:
              type: string
              description: >-
                Start date. Required and non-null when recurring.enabled=1 or
                recurring.enabled=true. YYYY-MM-DD is recommended. Must be no
                earlier than tomorrow in the service business timezone.
              nullable: true
              format: date
            end_date:
              type: string
              description: >-
                End date, preferably YYYY-MM-DD. Required and non-null when the
                recurring segment is enabled and recurring_type=4. When
                supplied, cannot precede start_date in the same segment.
              nullable: true
              format: date
            end_terms:
              type: integer
              description: >-
                Number of successful payments, an integer of at least 1.
                Required and non-null when the recurring segment is enabled and
                recurring_type=1.
              nullable: true
              minimum: 1
            total_amount:
              oneOf:
                - type: number
                  multipleOf: 0.01
                  minimum: 0.01
                  nullable: true
                - type: string
                  pattern: ^\d+(\.\d{1,2})?$
                  allOf:
                    - pattern: ^0*(?:[1-9]\d*(?:\.\d{1,2})?|0\.(?:0[1-9]|[1-9]\d?))$
              description: >-
                Target total amount in major currency units, with at most two
                decimal places and a minimum of 0.01. Accepts a number or
                numeric string. Required and non-null when the recurring segment
                is enabled and recurring_type=2. When amount and total_amount
                are both supplied in the same segment, amount must not exceed
                total_amount.
              nullable: true
            day_of_debit:
              type: string
              description: >-
                RFC 5545 RRULE debit rule. Required and non-null when the
                recurring segment is enabled. See the integration guide for
                frequency syntax. Must not place a debit day before start_date
                within the same cycle. Nonstandard intervals require
                process_type=12 and custom_cycle_type/custom_cycle.
              nullable: true
              maxLength: 255
            process_type:
              type: integer
              description: >-
                Provide 12 only for a custom frequency. Other frequencies are
                inferred from the RRULE; omit this field for them. Nonstandard
                RRULE intervals must use Custom.
              nullable: true
              enum:
                - 12
                - null
            custom_cycle_type:
              type: integer
              description: >-
                Required for process_type=12: 1 days, 2 weeks, 3 months, 4
                years. Must correspond to the RRULE FREQ. Non-Custom mode
                prohibits nonempty custom cycle parameters. Required and
                non-null when recurring.process_type=12.
              nullable: true
              enum:
                - 1
                - 2
                - 3
                - 4
                - null
            custom_cycle:
              type: integer
              description: >-
                Required for process_type=12. A positive integer equal to the
                RRULE INTERVAL. Minimum 5 for days and 1 for other units.
                Required and non-null when recurring.process_type=12.
              nullable: true
              minimum: 1
            day_of_debit_dtstart:
              type: string
              description: >-
                First debit anchor. Required for quarterly, half-yearly and
                yearly frequencies. YYYY-MM-DD is recommended; the date must be
                strictly after the corresponding start_date and within one
                billing cycle (3/6/12 months, clamped to month end). MM-DD is
                also accepted if it is a valid month/day; the full-date window
                restriction does not apply to that format.
              nullable: true
              pattern: ^(\d{4}-)?\d{2}-\d{2}$
          description: >-
            Supported top-level alternative; use `plan.recurring` for new
            integrations. If both forms supply this field, the nested value
            takes precedence.


            Recurring subscription definition.
          nullable: true
          not:
            anyOf:
              - allOf:
                  - required:
                      - enabled
                    properties:
                      enabled:
                        enum:
                          - true
                          - 1
                          - '1'
                  - not:
                      required:
                        - schedule_name
                        - recurring_type
                        - amount
                        - start_date
                        - day_of_debit
                      properties:
                        schedule_name:
                          not:
                            enum:
                              - null
                          minLength: 1
                        recurring_type:
                          not:
                            enum:
                              - null
                        amount:
                          not:
                            enum:
                              - null
                        start_date:
                          not:
                            enum:
                              - null
                          minLength: 1
                        day_of_debit:
                          not:
                            enum:
                              - null
                          minLength: 1
              - allOf:
                  - required:
                      - enabled
                      - recurring_type
                    properties:
                      enabled:
                        enum:
                          - true
                          - 1
                          - '1'
                      recurring_type:
                        enum:
                          - 1
                  - not:
                      required:
                        - end_terms
                      properties:
                        end_terms:
                          not:
                            enum:
                              - null
              - allOf:
                  - required:
                      - enabled
                      - recurring_type
                    properties:
                      enabled:
                        enum:
                          - true
                          - 1
                          - '1'
                      recurring_type:
                        enum:
                          - 2
                  - not:
                      required:
                        - total_amount
                      properties:
                        total_amount:
                          not:
                            enum:
                              - null
              - allOf:
                  - required:
                      - enabled
                      - recurring_type
                    properties:
                      enabled:
                        enum:
                          - true
                          - 1
                          - '1'
                      recurring_type:
                        enum:
                          - 4
                  - not:
                      required:
                        - end_date
                      properties:
                        end_date:
                          not:
                            enum:
                              - null
                          minLength: 1
              - allOf:
                  - required:
                      - process_type
                    properties:
                      process_type:
                        enum:
                          - 12
                  - not:
                      required:
                        - custom_cycle_type
                        - custom_cycle
                      properties:
                        custom_cycle_type:
                          not:
                            enum:
                              - null
                        custom_cycle:
                          not:
                            enum:
                              - null
              - allOf:
                  - required:
                      - process_type
                      - custom_cycle_type
                    properties:
                      process_type:
                        enum:
                          - 12
                      custom_cycle_type:
                        enum:
                          - 1
                  - not:
                      required:
                        - custom_cycle
                      properties:
                        custom_cycle:
                          not:
                            enum:
                              - null
                          minimum: 5
              - allOf:
                  - required:
                      - custom_cycle_type
                    properties:
                      custom_cycle_type:
                        not:
                          enum:
                            - null
                  - not:
                      required:
                        - process_type
                      properties:
                        process_type:
                          enum:
                            - 12
              - allOf:
                  - required:
                      - custom_cycle
                    properties:
                      custom_cycle:
                        not:
                          enum:
                            - null
                  - not:
                      required:
                        - process_type
                      properties:
                        process_type:
                          enum:
                            - 12
        one_off:
          type: object
          properties:
            enabled:
              description: >-
                Whether to enable this segment. Prefer integer 1 to enable or 0
                to disable; true/false and the strings "0"/"1" are also
                accepted. Manual mode must enable at least one segment. When
                enabled, provide all fields marked as required for the segment.
              nullable: true
              oneOf:
                - type: integer
                  enum:
                    - 0
                    - 1
                    - null
                  nullable: true
                - type: boolean
                - type: string
                  enum:
                    - '0'
                    - '1'
            schedule_name:
              type: string
              description: >-
                Payment schedule name. Required and non-null when
                one_off.enabled=1.
              nullable: true
              maxLength: 255
            amount:
              oneOf:
                - type: number
                  multipleOf: 0.01
                  minimum: 0.01
                  maximum: 9999999.99
                  nullable: true
                - type: string
                  pattern: ^\d+(\.\d{1,2})?$
                  allOf:
                    - pattern: >-
                        ^0*(?:[1-9]\d{0,6}(?:\.\d{1,2})?|0\.(?:0[1-9]|[1-9]\d?))$
              description: >-
                One-off or per-payment amount in major currency units, for
                example 10.50 means AUD 10.50. At most two decimal places.
                Numbers and numeric strings are accepted, with a minimum of 0.01
                and maximum of 9999999.99; the same range applies to both types.
                Required and non-null when one_off.enabled=1.
              nullable: true
            description:
              type: string
              description: Description.
              nullable: true
              maxLength: 500
            payment_date:
              type: string
              description: >-
                One-off debit date. Must be no earlier than tomorrow in the
                service business timezone. Required and non-null when
                one_off.enabled=1. YYYY-MM-DD is recommended. Cannot precede
                tomorrow in the service business timezone.
              nullable: true
              format: date
          description: >-
            Supported top-level alternative; use `plan.one_off` for new
            integrations. If both forms supply this field, the nested value
            takes precedence.


            One-off payment definition. Acts as a Deposit when enabled with
            recurring, or as a One-off when used alone.
          nullable: true
          not:
            anyOf:
              - allOf:
                  - required:
                      - enabled
                    properties:
                      enabled:
                        enum:
                          - true
                          - 1
                          - '1'
                  - not:
                      required:
                        - schedule_name
                        - amount
                        - payment_date
                      properties:
                        schedule_name:
                          not:
                            enum:
                              - null
                          minLength: 1
                        amount:
                          not:
                            enum:
                              - null
                        payment_date:
                          not:
                            enum:
                              - null
                          minLength: 1
        schedule:
          type: object
          properties:
            type:
              type: integer
              description: >-
                Initial By agreement schedule type: 1 after a number of
                successful payments; 2 at a cumulative amount; 3 until
                cancelled; 4 on an end date; 6 One-off. Types 5 and 7 are not
                supported.
              enum:
                - 1
                - 2
                - 3
                - 4
                - 6
            amount:
              oneOf:
                - type: number
                  multipleOf: 0.01
                  minimum: 0.01
                  maximum: 9999999.99
                - type: string
                  pattern: ^\d+(\.\d{1,2})?$
                  allOf:
                    - pattern: >-
                        ^0*(?:[1-9]\d{0,6}(?:\.\d{1,2})?|0\.(?:0[1-9]|[1-9]\d?))$
              description: >-
                One-off or per-payment amount in major currency units, for
                example 10.50 means AUD 10.50. At most two decimal places.
                Numbers and numeric strings are accepted, with a minimum of 0.01
                and maximum of 9999999.99; the same range applies to both types.
                Required and non-null when schedule is nonempty.
            start_date:
              type: string
              description: >-
                Start date. Required and non-null when schedule is nonempty.
                YYYY-MM-DD is recommended. Must be no earlier than tomorrow in
                the service business timezone.
              format: date
              minLength: 1
            schedule_name:
              type: string
              description: >-
                Payment schedule name. Required and non-null when schedule is
                nonempty; at most 255 characters.
              maxLength: 255
              minLength: 1
            total_amount:
              oneOf:
                - type: number
                  multipleOf: 0.01
                  minimum: 0.01
                  nullable: true
                - type: string
                  pattern: ^\d+(\.\d{1,2})?$
                  allOf:
                    - pattern: ^0*(?:[1-9]\d*(?:\.\d{1,2})?|0\.(?:0[1-9]|[1-9]\d?))$
              description: >-
                Target total amount in major currency units, with at most two
                decimal places and a minimum of 0.01. Accepts a number or
                numeric string. Required and non-null when schedule.type=2. When
                amount and total_amount are both supplied in the same segment,
                amount must not exceed total_amount.
              nullable: true
            day_of_debit:
              type: string
              description: >-
                RFC 5545 RRULE debit rule. Required and non-null for
                schedule.type=1/2/3/4; optional for type=6 (one-off). Must not
                place a debit day before start_date within the same cycle.
                Nonstandard intervals require process_type=12 and
                custom_cycle_type/custom_cycle.
              nullable: true
              maxLength: 255
            end_date:
              type: string
              description: >-
                End date, preferably YYYY-MM-DD. Required and non-null when
                schedule.type=4. When supplied, cannot precede start_date in the
                same segment.
              nullable: true
              format: date
            end_terms:
              type: integer
              description: >-
                Number of successful payments, an integer of at least 1.
                Required and non-null when schedule.type=1.
              nullable: true
              minimum: 1
            day_of_debit_dtstart:
              type: string
              description: >-
                First debit anchor. Required for quarterly, half-yearly and
                yearly frequencies. YYYY-MM-DD is recommended; the date must be
                strictly after the corresponding start_date and within one
                billing cycle (3/6/12 months, clamped to month end). MM-DD is
                also accepted if it is a valid month/day; the full-date window
                restriction does not apply to that format.
              nullable: true
              pattern: ^(\d{4}-)?\d{2}-\d{2}$
            process_type:
              type: integer
              description: >-
                Provide 12 only for a custom frequency. Other frequencies are
                inferred from the RRULE; omit this field for them. Nonstandard
                RRULE intervals must use Custom.
              nullable: true
              enum:
                - 12
                - null
            custom_cycle_type:
              type: integer
              description: >-
                Required for process_type=12: 1 days, 2 weeks, 3 months, 4
                years. Must correspond to the RRULE FREQ. Non-Custom mode
                prohibits nonempty custom cycle parameters. Required and
                non-null when schedule.process_type=12.
              nullable: true
              enum:
                - 1
                - 2
                - 3
                - 4
                - null
            custom_cycle:
              type: integer
              description: >-
                Required for process_type=12. A positive integer equal to the
                RRULE INTERVAL. Minimum 5 for days and 1 for other units.
                Required and non-null when schedule.process_type=12.
              nullable: true
              minimum: 1
          description: >-
            Supported top-level alternative; use `plan.schedule` for new
            integrations. If both forms supply this field, the nested value
            takes precedence.


            Initial By agreement payment schedule definition. Mutually exclusive
            with manual recurring/one_off mode and template_id mode.
          nullable: true
          required:
            - type
            - amount
            - start_date
            - schedule_name
          not:
            anyOf:
              - allOf:
                  - required:
                      - type
                    properties:
                      type:
                        enum:
                          - 1
                  - not:
                      required:
                        - end_terms
                      properties:
                        end_terms:
                          not:
                            enum:
                              - null
              - allOf:
                  - required:
                      - type
                    properties:
                      type:
                        enum:
                          - 2
                  - not:
                      required:
                        - total_amount
                      properties:
                        total_amount:
                          not:
                            enum:
                              - null
              - allOf:
                  - required:
                      - type
                    properties:
                      type:
                        enum:
                          - 4
                  - not:
                      required:
                        - end_date
                      properties:
                        end_date:
                          not:
                            enum:
                              - null
                          minLength: 1
              - allOf:
                  - required:
                      - type
                    properties:
                      type:
                        enum:
                          - 1
                          - 2
                          - 3
                          - 4
                  - not:
                      required:
                        - day_of_debit
                      properties:
                        day_of_debit:
                          not:
                            enum:
                              - null
                          minLength: 1
              - allOf:
                  - required:
                      - process_type
                    properties:
                      process_type:
                        enum:
                          - 12
                  - not:
                      required:
                        - custom_cycle_type
                        - custom_cycle
                      properties:
                        custom_cycle_type:
                          not:
                            enum:
                              - null
                        custom_cycle:
                          not:
                            enum:
                              - null
              - allOf:
                  - required:
                      - process_type
                      - custom_cycle_type
                    properties:
                      process_type:
                        enum:
                          - 12
                      custom_cycle_type:
                        enum:
                          - 1
                  - not:
                      required:
                        - custom_cycle
                      properties:
                        custom_cycle:
                          not:
                            enum:
                              - null
                          minimum: 5
              - allOf:
                  - required:
                      - custom_cycle_type
                    properties:
                      custom_cycle_type:
                        not:
                          enum:
                            - null
                  - not:
                      required:
                        - process_type
                      properties:
                        process_type:
                          enum:
                            - 12
              - allOf:
                  - required:
                      - custom_cycle
                    properties:
                      custom_cycle:
                        not:
                          enum:
                            - null
                  - not:
                      required:
                        - process_type
                      properties:
                        process_type:
                          enum:
                            - 12
        surcharge_config:
          type: array
          description: >-
            Supported top-level alternative; use `plan.surcharge_config` for new
            integrations. If both forms supply this field, the nested value
            takes precedence.


            Surcharge options, preferably an array of strings. See the schema
            and examples for allowed options. Omission, null or an empty array
            disables all options; non-array values are also treated as all
            disabled. Unknown options do not enable charges.
            credit_card_surcharge selects the credit card surcharge group.
            Actual charges depend on merchant business rules and payment method
            restrictions. Applies in manual mode. Template mode uses the
            template's surcharge options, which this field cannot override. By
            agreement schedule mode does not support this setting. Card
            surcharges remain subject to the applicable charging policy; if it
            prohibits them, selecting card options does not enable charges.
          nullable: true
          items:
            type: string
            description: Surcharge option.
            enum:
              - direct_debit_surcharge
              - visa_domestic_surcharge
              - visa_international_surcharge
              - mastercard_domestic_surcharge
              - mastercard_international_surcharge
              - amex_domestic_surcharge
              - amex_international_surcharge
              - credit_card_surcharge
        dishonour_fee_switch:
          description: >-
            Supported top-level alternative; use `plan.dishonour_fee_switch` for
            new integrations. If both forms supply this field, the nested value
            takes precedence.


            Whether to charge a customer dishonour fee. Omission or null
            defaults to off. Enabling it requires an applicable positive fee
            configuration; the signed terms determine the actual amount. Also
            accepts 0/1 and the strings "0"/"1". Applies only to manual
            recurring/one_off mode. Template mode and By agreement schedule mode
            do not support this setting through this field.
          nullable: true
          oneOf:
            - type: boolean
              nullable: true
            - type: integer
              enum:
                - 0
                - 1
            - type: string
              enum:
                - '0'
                - '1'
        template_id:
          type: string
          description: >-
            Supported top-level alternative; use `plan.template_id` for new
            integrations. If both forms supply this field, the nested value
            takes precedence.


            Available template ID from GET /api/v2/plan/list. Only enabled,
            ACTIVE, non-tiered templates other than By agreement are accepted.
          nullable: true
          maxLength: 20
        start_date:
          type: string
          description: >-
            Supported top-level alternative; use `plan.start_date` for new
            integrations. If both forms supply this field, the nested value
            takes precedence.


            Date override for the template's recurring segment. Required when
            the template contains recurring. Must be no earlier than tomorrow in
            the service business timezone.
          nullable: true
          format: date
        payment_date:
          type: string
          description: >-
            Supported top-level alternative; use `plan.payment_date` for new
            integrations. If both forms supply this field, the nested value
            takes precedence.


            Date override for the template's one_off segment. Required when the
            template contains one_off. Must be no earlier than tomorrow in the
            service business timezone.
          nullable: true
          format: date
      required:
        - merchant_id
      not:
        anyOf:
          - not:
              oneOf:
                - allOf:
                    - anyOf:
                        - type: object
                          required:
                            - customer
                          properties:
                            customer:
                              type: object
                              required:
                                - customer_id
                              properties:
                                customer_id:
                                  type: string
                                  minLength: 1
                                  pattern: \S
                        - allOf:
                            - not:
                                type: object
                                required:
                                  - customer
                                properties:
                                  customer:
                                    type: object
                                    required:
                                      - customer_id
                                    properties:
                                      customer_id: {}
                            - type: object
                              required:
                                - customer_id
                              properties:
                                customer_id:
                                  type: string
                                  minLength: 1
                                  pattern: \S
                    - not:
                        anyOf:
                          - anyOf:
                              - type: object
                                required:
                                  - customer
                                properties:
                                  customer:
                                    type: object
                                    required:
                                      - firstName
                                    properties:
                                      firstName:
                                        type: string
                                        minLength: 1
                                        pattern: \S
                              - allOf:
                                  - not:
                                      type: object
                                      required:
                                        - customer
                                      properties:
                                        customer:
                                          type: object
                                          required:
                                            - firstName
                                          properties:
                                            firstName: {}
                                  - type: object
                                    required:
                                      - firstName
                                    properties:
                                      firstName:
                                        type: string
                                        minLength: 1
                                        pattern: \S
                          - anyOf:
                              - type: object
                                required:
                                  - customer
                                properties:
                                  customer:
                                    type: object
                                    required:
                                      - lastName
                                    properties:
                                      lastName:
                                        type: string
                                        minLength: 1
                                        pattern: \S
                              - allOf:
                                  - not:
                                      type: object
                                      required:
                                        - customer
                                      properties:
                                        customer:
                                          type: object
                                          required:
                                            - lastName
                                          properties:
                                            lastName: {}
                                  - type: object
                                    required:
                                      - lastName
                                    properties:
                                      lastName:
                                        type: string
                                        minLength: 1
                                        pattern: \S
                          - anyOf:
                              - type: object
                                required:
                                  - customer
                                properties:
                                  customer:
                                    type: object
                                    required:
                                      - emailAddress
                                    properties:
                                      emailAddress:
                                        type: string
                                        minLength: 1
                                        pattern: \S
                              - allOf:
                                  - not:
                                      type: object
                                      required:
                                        - customer
                                      properties:
                                        customer:
                                          type: object
                                          required:
                                            - emailAddress
                                          properties:
                                            emailAddress: {}
                                  - type: object
                                    required:
                                      - emailAddress
                                    properties:
                                      emailAddress:
                                        type: string
                                        minLength: 1
                                        pattern: \S
                - allOf:
                    - not:
                        anyOf:
                          - type: object
                            required:
                              - customer
                            properties:
                              customer:
                                type: object
                                required:
                                  - customer_id
                                properties:
                                  customer_id:
                                    type: string
                                    minLength: 1
                                    pattern: \S
                          - allOf:
                              - not:
                                  type: object
                                  required:
                                    - customer
                                  properties:
                                    customer:
                                      type: object
                                      required:
                                        - customer_id
                                      properties:
                                        customer_id: {}
                              - type: object
                                required:
                                  - customer_id
                                properties:
                                  customer_id:
                                    type: string
                                    minLength: 1
                                    pattern: \S
                    - anyOf:
                        - type: object
                          required:
                            - customer
                          properties:
                            customer:
                              type: object
                              required:
                                - firstName
                              properties:
                                firstName:
                                  type: string
                                  minLength: 1
                                  pattern: \S
                        - allOf:
                            - not:
                                type: object
                                required:
                                  - customer
                                properties:
                                  customer:
                                    type: object
                                    required:
                                      - firstName
                                    properties:
                                      firstName: {}
                            - type: object
                              required:
                                - firstName
                              properties:
                                firstName:
                                  type: string
                                  minLength: 1
                                  pattern: \S
                    - anyOf:
                        - type: object
                          required:
                            - customer
                          properties:
                            customer:
                              type: object
                              required:
                                - lastName
                              properties:
                                lastName:
                                  type: string
                                  minLength: 1
                                  pattern: \S
                        - allOf:
                            - not:
                                type: object
                                required:
                                  - customer
                                properties:
                                  customer:
                                    type: object
                                    required:
                                      - lastName
                                    properties:
                                      lastName: {}
                            - type: object
                              required:
                                - lastName
                              properties:
                                lastName:
                                  type: string
                                  minLength: 1
                                  pattern: \S
                    - anyOf:
                        - type: object
                          required:
                            - customer
                          properties:
                            customer:
                              type: object
                              required:
                                - emailAddress
                              properties:
                                emailAddress:
                                  type: string
                                  minLength: 1
                                  pattern: \S
                        - allOf:
                            - not:
                                type: object
                                required:
                                  - customer
                                properties:
                                  customer:
                                    type: object
                                    required:
                                      - emailAddress
                                    properties:
                                      emailAddress: {}
                            - type: object
                              required:
                                - emailAddress
                              properties:
                                emailAddress:
                                  type: string
                                  minLength: 1
                                  pattern: \S
          - not:
              oneOf:
                - allOf:
                    - anyOf:
                        - type: object
                          required:
                            - plan
                          properties:
                            plan:
                              type: object
                              required:
                                - template_id
                              properties:
                                template_id:
                                  type: string
                                  minLength: 1
                                  pattern: \S
                        - allOf:
                            - not:
                                type: object
                                required:
                                  - plan
                                properties:
                                  plan:
                                    type: object
                                    required:
                                      - template_id
                                    properties:
                                      template_id: {}
                            - type: object
                              required:
                                - template_id
                              properties:
                                template_id:
                                  type: string
                                  minLength: 1
                                  pattern: \S
                    - not:
                        anyOf:
                          - type: object
                            required:
                              - plan
                            properties:
                              plan:
                                type: object
                                required:
                                  - schedule
                                properties:
                                  schedule:
                                    type: object
                                    minProperties: 1
                          - allOf:
                              - not:
                                  type: object
                                  required:
                                    - plan
                                  properties:
                                    plan:
                                      type: object
                                      required:
                                        - schedule
                                      properties:
                                        schedule: {}
                              - type: object
                                required:
                                  - schedule
                                properties:
                                  schedule:
                                    type: object
                                    minProperties: 1
                    - not:
                        anyOf:
                          - anyOf:
                              - type: object
                                required:
                                  - plan
                                properties:
                                  plan:
                                    type: object
                                    required:
                                      - recurring
                                    properties:
                                      recurring:
                                        type: object
                                        minProperties: 1
                              - allOf:
                                  - not:
                                      type: object
                                      required:
                                        - plan
                                      properties:
                                        plan:
                                          type: object
                                          required:
                                            - recurring
                                          properties:
                                            recurring: {}
                                  - type: object
                                    required:
                                      - recurring
                                    properties:
                                      recurring:
                                        type: object
                                        minProperties: 1
                          - anyOf:
                              - type: object
                                required:
                                  - plan
                                properties:
                                  plan:
                                    type: object
                                    required:
                                      - one_off
                                    properties:
                                      one_off:
                                        type: object
                                        minProperties: 1
                              - allOf:
                                  - not:
                                      type: object
                                      required:
                                        - plan
                                      properties:
                                        plan:
                                          type: object
                                          required:
                                            - one_off
                                          properties:
                                            one_off: {}
                                  - type: object
                                    required:
                                      - one_off
                                    properties:
                                      one_off:
                                        type: object
                                        minProperties: 1
                - allOf:
                    - anyOf:
                        - type: object
                          required:
                            - plan
                          properties:
                            plan:
                              type: object
                              required:
                                - schedule
                              properties:
                                schedule:
                                  type: object
                                  minProperties: 1
                        - allOf:
                            - not:
                                type: object
                                required:
                                  - plan
                                properties:
                                  plan:
                                    type: object
                                    required:
                                      - schedule
                                    properties:
                                      schedule: {}
                            - type: object
                              required:
                                - schedule
                              properties:
                                schedule:
                                  type: object
                                  minProperties: 1
                    - not:
                        anyOf:
                          - type: object
                            required:
                              - plan
                            properties:
                              plan:
                                type: object
                                required:
                                  - template_id
                                properties:
                                  template_id:
                                    type: string
                                    minLength: 1
                                    pattern: \S
                          - allOf:
                              - not:
                                  type: object
                                  required:
                                    - plan
                                  properties:
                                    plan:
                                      type: object
                                      required:
                                        - template_id
                                      properties:
                                        template_id: {}
                              - type: object
                                required:
                                  - template_id
                                properties:
                                  template_id:
                                    type: string
                                    minLength: 1
                                    pattern: \S
                    - not:
                        anyOf:
                          - anyOf:
                              - type: object
                                required:
                                  - plan
                                properties:
                                  plan:
                                    type: object
                                    required:
                                      - recurring
                                    properties:
                                      recurring:
                                        type: object
                                        minProperties: 1
                              - allOf:
                                  - not:
                                      type: object
                                      required:
                                        - plan
                                      properties:
                                        plan:
                                          type: object
                                          required:
                                            - recurring
                                          properties:
                                            recurring: {}
                                  - type: object
                                    required:
                                      - recurring
                                    properties:
                                      recurring:
                                        type: object
                                        minProperties: 1
                          - anyOf:
                              - type: object
                                required:
                                  - plan
                                properties:
                                  plan:
                                    type: object
                                    required:
                                      - one_off
                                    properties:
                                      one_off:
                                        type: object
                                        minProperties: 1
                              - allOf:
                                  - not:
                                      type: object
                                      required:
                                        - plan
                                      properties:
                                        plan:
                                          type: object
                                          required:
                                            - one_off
                                          properties:
                                            one_off: {}
                                  - type: object
                                    required:
                                      - one_off
                                    properties:
                                      one_off:
                                        type: object
                                        minProperties: 1
                - allOf:
                    - anyOf:
                        - anyOf:
                            - type: object
                              required:
                                - plan
                              properties:
                                plan:
                                  type: object
                                  required:
                                    - recurring
                                  properties:
                                    recurring:
                                      type: object
                                      minProperties: 1
                            - allOf:
                                - not:
                                    type: object
                                    required:
                                      - plan
                                    properties:
                                      plan:
                                        type: object
                                        required:
                                          - recurring
                                        properties:
                                          recurring: {}
                                - type: object
                                  required:
                                    - recurring
                                  properties:
                                    recurring:
                                      type: object
                                      minProperties: 1
                        - anyOf:
                            - type: object
                              required:
                                - plan
                              properties:
                                plan:
                                  type: object
                                  required:
                                    - one_off
                                  properties:
                                    one_off:
                                      type: object
                                      minProperties: 1
                            - allOf:
                                - not:
                                    type: object
                                    required:
                                      - plan
                                    properties:
                                      plan:
                                        type: object
                                        required:
                                          - one_off
                                        properties:
                                          one_off: {}
                                - type: object
                                  required:
                                    - one_off
                                  properties:
                                    one_off:
                                      type: object
                                      minProperties: 1
                    - not:
                        anyOf:
                          - type: object
                            required:
                              - plan
                            properties:
                              plan:
                                type: object
                                required:
                                  - template_id
                                properties:
                                  template_id:
                                    type: string
                                    minLength: 1
                                    pattern: \S
                          - allOf:
                              - not:
                                  type: object
                                  required:
                                    - plan
                                  properties:
                                    plan:
                                      type: object
                                      required:
                                        - template_id
                                      properties:
                                        template_id: {}
                              - type: object
                                required:
                                  - template_id
                                properties:
                                  template_id:
                                    type: string
                                    minLength: 1
                                    pattern: \S
                    - not:
                        anyOf:
                          - type: object
                            required:
                              - plan
                            properties:
                              plan:
                                type: object
                                required:
                                  - schedule
                                properties:
                                  schedule:
                                    type: object
                                    minProperties: 1
                          - allOf:
                              - not:
                                  type: object
                                  required:
                                    - plan
                                  properties:
                                    plan:
                                      type: object
                                      required:
                                        - schedule
                                      properties:
                                        schedule: {}
                              - type: object
                                required:
                                  - schedule
                                properties:
                                  schedule:
                                    type: object
                                    minProperties: 1
                    - anyOf:
                        - anyOf:
                            - type: object
                              required:
                                - plan
                              properties:
                                plan:
                                  type: object
                                  required:
                                    - recurring
                                  properties:
                                    recurring:
                                      type: object
                                      required:
                                        - enabled
                                      properties:
                                        enabled:
                                          enum:
                                            - true
                                            - 1
                                            - '1'
                            - allOf:
                                - not:
                                    type: object
                                    required:
                                      - plan
                                    properties:
                                      plan:
                                        type: object
                                        required:
                                          - recurring
                                        properties:
                                          recurring: {}
                                - type: object
                                  required:
                                    - recurring
                                  properties:
                                    recurring:
                                      type: object
                                      required:
                                        - enabled
                                      properties:
                                        enabled:
                                          enum:
                                            - true
                                            - 1
                                            - '1'
                        - anyOf:
                            - type: object
                              required:
                                - plan
                              properties:
                                plan:
                                  type: object
                                  required:
                                    - one_off
                                  properties:
                                    one_off:
                                      type: object
                                      required:
                                        - enabled
                                      properties:
                                        enabled:
                                          enum:
                                            - true
                                            - 1
                                            - '1'
                            - allOf:
                                - not:
                                    type: object
                                    required:
                                      - plan
                                    properties:
                                      plan:
                                        type: object
                                        required:
                                          - one_off
                                        properties:
                                          one_off: {}
                                - type: object
                                  required:
                                    - one_off
                                  properties:
                                    one_off:
                                      type: object
                                      required:
                                        - enabled
                                      properties:
                                        enabled:
                                          enum:
                                            - true
                                            - 1
                                            - '1'
          - allOf:
              - allOf:
                  - not:
                      type: object
                      required:
                        - plan
                      properties:
                        plan:
                          type: object
                          required:
                            - template_id
                          properties:
                            template_id:
                              type: string
                              minLength: 1
                              pattern: \S
                  - anyOf:
                      - type: object
                        required:
                          - plan
                        properties:
                          plan:
                            type: object
                            required:
                              - template_id
                            properties:
                              template_id: {}
                      - not:
                          type: object
                          required:
                            - template_id
                          properties:
                            template_id:
                              type: string
                              minLength: 1
                              pattern: \S
              - allOf:
                  - not:
                      type: object
                      required:
                        - plan
                      properties:
                        plan:
                          type: object
                          required:
                            - plan_name
                          properties:
                            plan_name:
                              type: string
                              minLength: 1
                              pattern: \S
                  - anyOf:
                      - type: object
                        required:
                          - plan
                        properties:
                          plan:
                            type: object
                            required:
                              - plan_name
                            properties:
                              plan_name: {}
                      - not:
                          type: object
                          required:
                            - plan_name
                          properties:
                            plan_name:
                              type: string
                              minLength: 1
                              pattern: \S
          - allOf:
              - anyOf:
                  - type: object
                    required:
                      - plan
                    properties:
                      plan:
                        type: object
                        required:
                          - template_id
                        properties:
                          template_id:
                            type: string
                            minLength: 1
                            pattern: \S
                  - allOf:
                      - not:
                          type: object
                          required:
                            - plan
                          properties:
                            plan:
                              type: object
                              required:
                                - template_id
                              properties:
                                template_id: {}
                      - type: object
                        required:
                          - template_id
                        properties:
                          template_id:
                            type: string
                            minLength: 1
                            pattern: \S
              - allOf:
                  - not:
                      type: object
                      required:
                        - plan
                      properties:
                        plan:
                          type: object
                          required:
                            - start_date
                          properties:
                            start_date:
                              type: string
                              minLength: 1
                              pattern: \S
                  - anyOf:
                      - type: object
                        required:
                          - plan
                        properties:
                          plan:
                            type: object
                            required:
                              - start_date
                            properties:
                              start_date: {}
                      - not:
                          type: object
                          required:
                            - start_date
                          properties:
                            start_date:
                              type: string
                              minLength: 1
                              pattern: \S
              - allOf:
                  - not:
                      type: object
                      required:
                        - plan
                      properties:
                        plan:
                          type: object
                          required:
                            - payment_date
                          properties:
                            payment_date:
                              type: string
                              minLength: 1
                              pattern: \S
                  - anyOf:
                      - type: object
                        required:
                          - plan
                        properties:
                          plan:
                            type: object
                            required:
                              - payment_date
                            properties:
                              payment_date: {}
                      - not:
                          type: object
                          required:
                            - payment_date
                          properties:
                            payment_date:
                              type: string
                              minLength: 1
                              pattern: \S
    SubscriptionCreateResponse:
      type: object
      description: Success response.
      properties:
        code:
          type: integer
          description: 0 means the subscription was created and awaits customer activation.
          enum:
            - 0
        message:
          type: string
          description: Response message.
        data:
          type: object
          description: Created DDR awaiting activation.
          properties:
            customer_id:
              type: string
              description: BillBuddy customer identifier.
            plan_id:
              type: string
              description: DDR subscription ID.
            status:
              type: integer
              description: >-
                DDR status: 1 Active, 2 Inactive, 3 Processing, 4 Processed, 5
                On Hold, 6 Completed, 7 Cancelled, 8 Paused, 9 Expired.
              enum:
                - 2
            is_by_agreement:
              type: boolean
              description: Returns true only in By agreement mode.
            activation_url:
              type: string
              description: >-
                Complete hosted activation page URL. Use it unchanged for a
                browser redirect or iframe src; do not construct the URL or
                parse its credentials. A success response may omit this field.
                If missing, contact BillBuddy to check the created subscription
                before proceeding. For recurring and By agreement subscriptions,
                use it before start_date. For one-off-only subscriptions, submit
                activation within 30 days of creation.
              format: uri
            activation_html:
              type: string
              description: >-
                HTML suitable for iframe srcdoc that directs the customer to
                activation_url. A success response may omit this field; handle
                it as described for activation_url.
          required:
            - customer_id
            - plan_id
            - status
      required:
        - code
        - message
        - data
    BusinessError:
      type: object
      description: Business error. HTTP status is usually still 200.
      properties:
        code:
          type: integer
          description: >-
            Business and authentication errors use 1; request parameter and
            upload file property validation errors use 400.
          enum:
            - 1
            - 400
        message:
          type: string
          description: Error reason. The exact message varies by cause.
        data:
          oneOf:
            - type: object
              description: Empty object or error context.
              properties:
                customer_id:
                  type: string
                  description: >-
                    If a later createDdr step fails, this may identify a
                    customer that was created and retained. Reuse this ID when
                    retrying.
            - type: array
              items: {}
              description: Usually an empty array.
          description: >-
            Error data: may be [], {} or customer context containing
            customer_id.
      required:
        - code
        - message
        - data
  securitySchemes:
    oauth2:
      type: oauth2
      description: >-
        OAuth2 client_credentials authorization. Obtain a new access_token when
        it expires.
      flows:
        clientCredentials:
          tokenUrl: /oauth/token
          scopes: {}

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.