> ## 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 direct payment

> ### Parameters by transaction operation

Every operation requires `trans_func`, `merchant_id`, `amount`, `merchant_order_no` and `currency`. Add the conditional fields below, including when using an existing customer.

| trans_func | Operation | Additional required fields |
| --- | --- | --- |
| 1 | Create a token without charging | `card.card_number`, `card.expiration_month`, `card.expiration_year`, `card.security_code`, `first_name`, `last_name` |
| 2 | Token payment | `card_token`, `first_name`, `last_name` |
| 3 | Card number payment | `card.card_number`, `card.expiration_month`, `card.expiration_year`, `card.security_code`, `first_name`, `last_name` |
| 4 | Create checkout | `return_url` |
| 5 | Bank account payment | `bank_account.bsb`, `bank_account.account_no`, `bank_account.account_name`; do not supply a non-empty `card` |

`is3ds=1` also requires `return_url`. `process_date` supports only operations 2, 3 and 5, must be strictly after today in the business timezone, and cannot be combined with `is3ds=1`. See each field for types, lengths and value limits.

Supports payment token creation, token payments, card payments, hosted checkout and bank account payments. Scheduling is not allowed when is3ds=1. Display the HTML to guide customer authentication only when response data.html is nonempty. If html is empty, handle the returned status; do not assume an authentication page is required. Do not submit a nonempty card when trans_func=5. The processing date must be strictly after today in the service business timezone. data.sign is the response signature; example 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. Example signatures are not valid for real transactions. A payment failure returns top-level code=1, and data contains no transaction details.

A declined payment or failed 3DS authentication returns top-level code=1 and data=[]. See message for the reason. Do not read data.status as if this were a success response.

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/trans/directPay
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/trans/directPay:
    post:
      tags:
        - Transactions
      summary: Create a direct payment
      description: >-
        ### Parameters by transaction operation


        Every operation requires `trans_func`, `merchant_id`, `amount`,
        `merchant_order_no` and `currency`. Add the conditional fields below,
        including when using an existing customer.


        | trans_func | Operation | Additional required fields |

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

        | 1 | Create a token without charging | `card.card_number`,
        `card.expiration_month`, `card.expiration_year`, `card.security_code`,
        `first_name`, `last_name` |

        | 2 | Token payment | `card_token`, `first_name`, `last_name` |

        | 3 | Card number payment | `card.card_number`, `card.expiration_month`,
        `card.expiration_year`, `card.security_code`, `first_name`, `last_name`
        |

        | 4 | Create checkout | `return_url` |

        | 5 | Bank account payment | `bank_account.bsb`,
        `bank_account.account_no`, `bank_account.account_name`; do not supply a
        non-empty `card` |


        `is3ds=1` also requires `return_url`. `process_date` supports only
        operations 2, 3 and 5, must be strictly after today in the business
        timezone, and cannot be combined with `is3ds=1`. See each field for
        types, lengths and value limits.


        Supports payment token creation, token payments, card payments, hosted
        checkout and bank account payments. Scheduling is not allowed when
        is3ds=1. Display the HTML to guide customer authentication only when
        response data.html is nonempty. If html is empty, handle the returned
        status; do not assume an authentication page is required. Do not submit
        a nonempty card when trans_func=5. The processing date must be strictly
        after today in the service business timezone. data.sign is the response
        signature; example 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. Example signatures are not valid for real
        transactions. A payment failure returns top-level code=1, and data
        contains no transaction details.


        A declined payment or failed 3DS authentication returns top-level code=1
        and data=[]. See message for the reason. Do not read data.status as if
        this were a success response.


        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: v2DirectPay
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DirectPayRequest'
            examples:
              card:
                summary: Immediate card payment
                value:
                  merchant_id: '48290713'
                  amount: '25.50'
                  merchant_order_no: BB-20300101-001
                  currency: AUD
                  trans_func: 3
                  first_name: Emily
                  last_name: Carter
                  card:
                    card_number: '4111111111111111'
                    expiration_month: '12'
                    expiration_year: '2030'
                    security_code: '123'
                  notify_email: false
                  notify_sms: false
              customerToken:
                summary: Existing customer token payment
                value:
                  merchant_id: '48290713'
                  amount: '25.50'
                  merchant_order_no: BB-20300101-002
                  currency: AUD
                  trans_func: 2
                  customer_id: CUS48290713
                  card_token: 4a9c8e71d6b24f03a58d19c7e2046b35
                  first_name: Emily
                  last_name: Carter
              createToken:
                summary: Create a token without charging
                value:
                  merchant_id: '48290713'
                  amount: '25.50'
                  merchant_order_no: BB-20300101-003
                  currency: AUD
                  trans_func: 1
                  first_name: Emily
                  last_name: Carter
                  card:
                    card_number: '4111111111111111'
                    expiration_month: '12'
                    expiration_year: '2030'
                    security_code: '123'
              checkout:
                summary: Create a checkout session
                value:
                  merchant_id: '48290713'
                  amount: '25.50'
                  merchant_order_no: BB-20300101-004
                  currency: AUD
                  trans_func: 4
                  return_url: https://portal.example.com/payments/complete
              bank:
                summary: Scheduled bank account payment
                value:
                  merchant_id: '48290713'
                  amount: '25.50'
                  merchant_order_no: BB-20300101-005
                  currency: AUD
                  trans_func: 5
                  bank_account:
                    bsb: 062-000
                    account_no: '618472950'
                    account_name: Emily Carter
                  process_date: '2030-01-15'
              card3ds:
                summary: Card payment with 3DS
                value:
                  merchant_id: '48290713'
                  amount: '25.50'
                  merchant_order_no: BB-20300101-006
                  currency: AUD
                  trans_func: 3
                  first_name: Emily
                  last_name: Carter
                  card:
                    card_number: '4111111111111111'
                    expiration_month: '12'
                    expiration_year: '2030'
                    security_code: '123'
                  is3ds: 1
                  return_url: https://portal.example.com/payments/complete
              scheduledCard:
                summary: Scheduled card payment
                value:
                  merchant_id: '48290713'
                  amount: '25.50'
                  merchant_order_no: BB-20300101-007
                  currency: AUD
                  trans_func: 3
                  first_name: Emily
                  last_name: Carter
                  card:
                    card_number: '4111111111111111'
                    expiration_month: '12'
                    expiration_year: '2030'
                    security_code: '123'
                  process_date: '2030-01-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/DirectPayResponse'
                  - $ref: '#/components/schemas/BusinessError'
              examples:
                success:
                  summary: >-
                    Successful immediate payment with a signature calculated
                    using the demo key
                  value:
                    code: 0
                    message: ok
                    data:
                      business_id: '7294815'
                      merchant_id: '48290713'
                      order_number: b1893452400000741
                      merchant_order_no: BB-20300101-001
                      trans_func: 3
                      complete_date: 01/01/2030 10:00:00
                      currency: AUD
                      amount: '25.50'
                      html: ''
                      card_token: ''
                      status: 1
                      code: 0
                      remark: Approved
                      sign_type: SHA256
                      sign: >-
                        fc6d0b575bb56a05607a71a8b78fecae9ba07275626bde9d0afed3f959c3910b
                pendingBank:
                  summary: Scheduled request accepted; no payment collected yet
                  value:
                    code: 0
                    message: ok
                    data:
                      business_id: '7294815'
                      merchant_id: '48290713'
                      order_number: b1893452400000826
                      merchant_order_no: BB-20300101-005
                      trans_func: 5
                      complete_date: 01/01/2030 10:00:00
                      currency: AUD
                      amount: '25.50'
                      html: ''
                      card_token: ''
                      status: 3
                      code: 0
                      remark: ''
                      sign_type: SHA256
                      sign: >-
                        72fe7ee2a8f8cf64301fc75ae042c4ce491b3668c3716b350ef7fa1afc0ec95d
                      process_date: '2030-01-15'
                      cancel_deadline: '2030-01-15 08:15:00'
                checkout:
                  summary: Checkout session
                  value:
                    code: 0
                    message: ok
                    data:
                      checkout_url: >-
                        https://staging-api.billbuddyhq.com/pay/K8mV4qR2sT7nW9xY3aB6cD1eF5gH0jL4
                      expires_at: 01/01/2030 10:30:00
                createToken:
                  summary: Token created; this does not indicate a charge
                  value:
                    code: 0
                    message: ok
                    data:
                      business_id: '7294815'
                      merchant_id: '48290713'
                      order_number: b1893452400000395
                      merchant_order_no: BB-20300101-003
                      trans_func: 1
                      complete_date: 01/01/2030 10:00:00
                      currency: AUD
                      amount: '25.50'
                      html: ''
                      card_token: 4a9c8e71d6b24f03a58d19c7e2046b35
                      status: 1
                      code: 0
                      remark: ''
                      sign_type: SHA256
                      sign: >-
                        a77dbc2f960fd20d89120591d6998f299306fb03e75a916d8cc53bb8df1e49ba
                3ds:
                  summary: Customer must complete 3DS authentication
                  value:
                    code: 0
                    message: ok
                    data:
                      business_id: '7294815'
                      merchant_id: '48290713'
                      order_number: ''
                      merchant_order_no: BB-20300101-006
                      trans_func: 3
                      complete_date: 01/01/2030 10:00:00
                      currency: AUD
                      amount: '25.50'
                      html: >-
                        <form id="step-up-form" target="_top" method="post"
                        action="https://issuer.example.com/3ds"><input
                        type="hidden" name="JWT"
                        value="eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL3BheW1lbnRzLmV4YW1wbGUuY29tIiwiYXVkIjoiaHR0cHM6Ly9pc3N1ZXIuZXhhbXBsZS5jb20vM2RzIiwiaWF0IjoxODkzNDUyNDAwLCJleHAiOjE4OTM0NTMwMDAsImp0aSI6IjhmYWU1ZDcyLTNiOTQtNGE2MS1hMGM4LTUyN2QxOTZlNGIzMCJ9.OIIccfj_Nl9_nYNUzPdodNGmnRBTgID-fgZG283MuDhGN70bi80GWoPBIqvCk_Og8EuLa8pUNTIUYHpyO6_mBqLmmPNpd-kIfKvV8D3SaLA8RVugrOU9u4ZrbIg3wguhriX6vKwGiAuPxLOjSc2N0N8xHWmb7EK90KxiZ2GefvDz1T_h0x_WSoKGaKjtAjgE8XhUmuuCVXYChaID4m6XusokUWKJXVHmr7NbTyK-I_St1Umf3Fw5CzKRJ_uupLNWIhLMtbGmFBTTOIVbZbq2XXxJItf5IKPHZdAi0YS_HRC3OMhgMUYv4M8MkRAATk9477irkguqqZkbyJ4ctMI0fw"
                        /><input type="hidden" name="MD"
                        value="optionally_include_custom_data_that_will_be_returned_as_is"
                        /></form><script>window.onload=function(){var
                        stepUpForm=document.querySelector("#step-up-form");if(stepUpForm){stepUpForm.submit();}};</script>
                      card_token: ''
                      status: 3
                      code: 0
                      remark: ''
                      sign_type: SHA256
                      sign: >-
                        d0bc67e7ea1bbfefed44775aae78ac43de75da0348f5702af6c6adad862d61e7
                failure:
                  summary: Business error
                  value:
                    code: 1
                    message: Order already exists
                    data: []
                validation:
                  summary: Invalid request parameters
                  value:
                    code: 400
                    message: The amount field is required.
                    data: {}
                auth:
                  summary: OAuth authentication failure with HTTP 200
                  value:
                    code: 1
                    message: Unauthenticated, invalid or expired access token
                    data: []
                scheduledCard:
                  summary: Scheduled card payment accepted; no payment collected yet
                  value:
                    code: 0
                    message: ok
                    data:
                      business_id: '7294815'
                      merchant_id: '48290713'
                      order_number: b1893452400000608
                      merchant_order_no: BB-20300101-007
                      trans_func: 3
                      complete_date: 01/01/2030 10:00:00
                      currency: AUD
                      amount: '25.50'
                      html: ''
                      card_token: ''
                      status: 3
                      code: 0
                      remark: ''
                      sign_type: SHA256
                      sign: >-
                        138fae206fcd0aef39a47dc82ac5ebe642ff1159934170c6f0e44594d0b9b757
                      process_date: '2030-01-15'
                      cancel_deadline: '2030-01-15 08:15:00'
                customerToken:
                  summary: Successful token payment for an existing customer
                  value:
                    code: 0
                    message: ok
                    data:
                      business_id: '7294815'
                      merchant_id: '48290713'
                      order_number: b1893452400000512
                      merchant_order_no: BB-20300101-002
                      trans_func: 2
                      complete_date: 01/01/2030 10:00:00
                      currency: AUD
                      amount: '25.50'
                      html: ''
                      card_token: 4a9c8e71d6b24f03a58d19c7e2046b35
                      status: 1
                      code: 0
                      remark: Approved
                      sign_type: SHA256
                      sign: >-
                        f613ac5ea86285675c7c01cb5e973d3ee3b62efa44406ab0312594f07270e41e
                declined:
                  summary: Payment declined; see message for the specific reason
                  value:
                    code: 1
                    message: Payment failed Declined
                    data: []
                threeDsFailure:
                  summary: >-
                    3DS authentication failed; see message for the specific
                    reason
                  value:
                    code: 1
                    message: '3DS authentication failed: Authentication declined'
                    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: Immediate card payment
          source: |-
            curl -X POST "${BASE_URL}/api/v2/trans/directPay" \
              -H "Authorization: Bearer ${ACCESS_TOKEN}" \
              -H "Accept: application/json" \
              -H "Content-Type: application/json" \
              --data-raw '{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-001",
              "currency": "AUD",
              "trans_func": 3,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              },
              "notify_email": false,
              "notify_sms": false
            }'
        - lang: Shell
          label: Existing customer token payment
          source: |-
            curl -X POST "${BASE_URL}/api/v2/trans/directPay" \
              -H "Authorization: Bearer ${ACCESS_TOKEN}" \
              -H "Accept: application/json" \
              -H "Content-Type: application/json" \
              --data-raw '{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-002",
              "currency": "AUD",
              "trans_func": 2,
              "customer_id": "CUS48290713",
              "card_token": "4a9c8e71d6b24f03a58d19c7e2046b35",
              "first_name": "Emily",
              "last_name": "Carter"
            }'
        - lang: Shell
          label: Create a token without charging
          source: |-
            curl -X POST "${BASE_URL}/api/v2/trans/directPay" \
              -H "Authorization: Bearer ${ACCESS_TOKEN}" \
              -H "Accept: application/json" \
              -H "Content-Type: application/json" \
              --data-raw '{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-003",
              "currency": "AUD",
              "trans_func": 1,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              }
            }'
        - lang: Shell
          label: Create a checkout session
          source: |-
            curl -X POST "${BASE_URL}/api/v2/trans/directPay" \
              -H "Authorization: Bearer ${ACCESS_TOKEN}" \
              -H "Accept: application/json" \
              -H "Content-Type: application/json" \
              --data-raw '{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-004",
              "currency": "AUD",
              "trans_func": 4,
              "return_url": "https://portal.example.com/payments/complete"
            }'
        - lang: Shell
          label: Scheduled bank account payment
          source: |-
            curl -X POST "${BASE_URL}/api/v2/trans/directPay" \
              -H "Authorization: Bearer ${ACCESS_TOKEN}" \
              -H "Accept: application/json" \
              -H "Content-Type: application/json" \
              --data-raw '{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-005",
              "currency": "AUD",
              "trans_func": 5,
              "bank_account": {
                "bsb": "062-000",
                "account_no": "618472950",
                "account_name": "Emily Carter"
              },
              "process_date": "2030-01-15"
            }'
        - lang: Shell
          label: Card payment with 3DS
          source: |-
            curl -X POST "${BASE_URL}/api/v2/trans/directPay" \
              -H "Authorization: Bearer ${ACCESS_TOKEN}" \
              -H "Accept: application/json" \
              -H "Content-Type: application/json" \
              --data-raw '{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-006",
              "currency": "AUD",
              "trans_func": 3,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              },
              "is3ds": 1,
              "return_url": "https://portal.example.com/payments/complete"
            }'
        - lang: Shell
          label: Scheduled card payment
          source: |-
            curl -X POST "${BASE_URL}/api/v2/trans/directPay" \
              -H "Authorization: Bearer ${ACCESS_TOKEN}" \
              -H "Accept: application/json" \
              -H "Content-Type: application/json" \
              --data-raw '{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-007",
              "currency": "AUD",
              "trans_func": 3,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              },
              "process_date": "2030-01-15"
            }'
        - lang: Python
          label: Immediate card payment
          source: >
            import json

            import os

            import urllib.parse

            import urllib.request


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

            url = base_url + "/api/v2/trans/directPay"

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

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

            payload = json.loads(r'''{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-001",
              "currency": "AUD",
              "trans_func": 3,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              },
              "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: Existing customer token payment
          source: >
            import json

            import os

            import urllib.parse

            import urllib.request


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

            url = base_url + "/api/v2/trans/directPay"

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

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

            payload = json.loads(r'''{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-002",
              "currency": "AUD",
              "trans_func": 2,
              "customer_id": "CUS48290713",
              "card_token": "4a9c8e71d6b24f03a58d19c7e2046b35",
              "first_name": "Emily",
              "last_name": "Carter"
            }''')

            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: Create a token without charging
          source: >
            import json

            import os

            import urllib.parse

            import urllib.request


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

            url = base_url + "/api/v2/trans/directPay"

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

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

            payload = json.loads(r'''{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-003",
              "currency": "AUD",
              "trans_func": 1,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              }
            }''')

            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: Create a checkout session
          source: >
            import json

            import os

            import urllib.parse

            import urllib.request


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

            url = base_url + "/api/v2/trans/directPay"

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

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

            payload = json.loads(r'''{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-004",
              "currency": "AUD",
              "trans_func": 4,
              "return_url": "https://portal.example.com/payments/complete"
            }''')

            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: Scheduled bank account payment
          source: >
            import json

            import os

            import urllib.parse

            import urllib.request


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

            url = base_url + "/api/v2/trans/directPay"

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

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

            payload = json.loads(r'''{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-005",
              "currency": "AUD",
              "trans_func": 5,
              "bank_account": {
                "bsb": "062-000",
                "account_no": "618472950",
                "account_name": "Emily Carter"
              },
              "process_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: Card payment with 3DS
          source: >
            import json

            import os

            import urllib.parse

            import urllib.request


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

            url = base_url + "/api/v2/trans/directPay"

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

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

            payload = json.loads(r'''{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-006",
              "currency": "AUD",
              "trans_func": 3,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              },
              "is3ds": 1,
              "return_url": "https://portal.example.com/payments/complete"
            }''')

            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: Scheduled card payment
          source: >
            import json

            import os

            import urllib.parse

            import urllib.request


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

            url = base_url + "/api/v2/trans/directPay"

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

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

            payload = json.loads(r'''{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-007",
              "currency": "AUD",
              "trans_func": 3,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              },
              "process_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: JavaScript
          label: Immediate card payment
          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/trans/directPay");
            const headers = { Accept: "application/json" };
            headers.Authorization = `Bearer ${env("ACCESS_TOKEN")}`;
            const payload = {
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-001",
              "currency": "AUD",
              "trans_func": 3,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              },
              "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: Existing customer token payment
          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/trans/directPay");
            const headers = { Accept: "application/json" };
            headers.Authorization = `Bearer ${env("ACCESS_TOKEN")}`;
            const payload = {
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-002",
              "currency": "AUD",
              "trans_func": 2,
              "customer_id": "CUS48290713",
              "card_token": "4a9c8e71d6b24f03a58d19c7e2046b35",
              "first_name": "Emily",
              "last_name": "Carter"
            };
            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: Create a token without charging
          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/trans/directPay");
            const headers = { Accept: "application/json" };
            headers.Authorization = `Bearer ${env("ACCESS_TOKEN")}`;
            const payload = {
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-003",
              "currency": "AUD",
              "trans_func": 1,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              }
            };
            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: Create a checkout session
          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/trans/directPay");
            const headers = { Accept: "application/json" };
            headers.Authorization = `Bearer ${env("ACCESS_TOKEN")}`;
            const payload = {
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-004",
              "currency": "AUD",
              "trans_func": 4,
              "return_url": "https://portal.example.com/payments/complete"
            };
            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: Scheduled bank account payment
          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/trans/directPay");
            const headers = { Accept: "application/json" };
            headers.Authorization = `Bearer ${env("ACCESS_TOKEN")}`;
            const payload = {
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-005",
              "currency": "AUD",
              "trans_func": 5,
              "bank_account": {
                "bsb": "062-000",
                "account_no": "618472950",
                "account_name": "Emily Carter"
              },
              "process_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: Card payment with 3DS
          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/trans/directPay");
            const headers = { Accept: "application/json" };
            headers.Authorization = `Bearer ${env("ACCESS_TOKEN")}`;
            const payload = {
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-006",
              "currency": "AUD",
              "trans_func": 3,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              },
              "is3ds": 1,
              "return_url": "https://portal.example.com/payments/complete"
            };
            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: Scheduled card payment
          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/trans/directPay");
            const headers = { Accept: "application/json" };
            headers.Authorization = `Bearer ${env("ACCESS_TOKEN")}`;
            const payload = {
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-007",
              "currency": "AUD",
              "trans_func": 3,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              },
              "process_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: PHP
          label: Immediate card payment
          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/trans/directPay";
            $headers = ['Accept: application/json'];
            $headers[] = 'Authorization: Bearer ' . $env('ACCESS_TOKEN');
            $body = <<<'JSON'
            {
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-001",
              "currency": "AUD",
              "trans_func": 3,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              },
              "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: Existing customer token payment
          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/trans/directPay";
            $headers = ['Accept: application/json'];
            $headers[] = 'Authorization: Bearer ' . $env('ACCESS_TOKEN');
            $body = <<<'JSON'
            {
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-002",
              "currency": "AUD",
              "trans_func": 2,
              "customer_id": "CUS48290713",
              "card_token": "4a9c8e71d6b24f03a58d19c7e2046b35",
              "first_name": "Emily",
              "last_name": "Carter"
            }
            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: Create a token without charging
          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/trans/directPay";
            $headers = ['Accept: application/json'];
            $headers[] = 'Authorization: Bearer ' . $env('ACCESS_TOKEN');
            $body = <<<'JSON'
            {
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-003",
              "currency": "AUD",
              "trans_func": 1,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              }
            }
            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: Create a checkout session
          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/trans/directPay";
            $headers = ['Accept: application/json'];
            $headers[] = 'Authorization: Bearer ' . $env('ACCESS_TOKEN');
            $body = <<<'JSON'
            {
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-004",
              "currency": "AUD",
              "trans_func": 4,
              "return_url": "https://portal.example.com/payments/complete"
            }
            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: Scheduled bank account payment
          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/trans/directPay";
            $headers = ['Accept: application/json'];
            $headers[] = 'Authorization: Bearer ' . $env('ACCESS_TOKEN');
            $body = <<<'JSON'
            {
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-005",
              "currency": "AUD",
              "trans_func": 5,
              "bank_account": {
                "bsb": "062-000",
                "account_no": "618472950",
                "account_name": "Emily Carter"
              },
              "process_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: Card payment with 3DS
          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/trans/directPay";
            $headers = ['Accept: application/json'];
            $headers[] = 'Authorization: Bearer ' . $env('ACCESS_TOKEN');
            $body = <<<'JSON'
            {
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-006",
              "currency": "AUD",
              "trans_func": 3,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              },
              "is3ds": 1,
              "return_url": "https://portal.example.com/payments/complete"
            }
            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: Scheduled card payment
          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/trans/directPay";
            $headers = ['Accept: application/json'];
            $headers[] = 'Authorization: Bearer ' . $env('ACCESS_TOKEN');
            $body = <<<'JSON'
            {
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-007",
              "currency": "AUD",
              "trans_func": 3,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              },
              "process_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: Go
          label: Immediate card payment
          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/trans/directPay"
                payload := `{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-001",
              "currency": "AUD",
              "trans_func": 3,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              },
              "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: Existing customer token payment
          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/trans/directPay"
                payload := `{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-002",
              "currency": "AUD",
              "trans_func": 2,
              "customer_id": "CUS48290713",
              "card_token": "4a9c8e71d6b24f03a58d19c7e2046b35",
              "first_name": "Emily",
              "last_name": "Carter"
            }`
                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: Create a token without charging
          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/trans/directPay"
                payload := `{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-003",
              "currency": "AUD",
              "trans_func": 1,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              }
            }`
                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: Create a checkout session
          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/trans/directPay"
                payload := `{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-004",
              "currency": "AUD",
              "trans_func": 4,
              "return_url": "https://portal.example.com/payments/complete"
            }`
                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: Scheduled bank account payment
          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/trans/directPay"
                payload := `{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-005",
              "currency": "AUD",
              "trans_func": 5,
              "bank_account": {
                "bsb": "062-000",
                "account_no": "618472950",
                "account_name": "Emily Carter"
              },
              "process_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: Card payment with 3DS
          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/trans/directPay"
                payload := `{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-006",
              "currency": "AUD",
              "trans_func": 3,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              },
              "is3ds": 1,
              "return_url": "https://portal.example.com/payments/complete"
            }`
                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: Scheduled card payment
          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/trans/directPay"
                payload := `{
              "merchant_id": "48290713",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-007",
              "currency": "AUD",
              "trans_func": 3,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              },
              "process_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: Java
          label: Immediate card payment
          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/trans/directPay";
                    String payload =
                        "{\n" +
                        "  \"merchant_id\": \"48290713\",\n" +
                        "  \"amount\": \"25.50\",\n" +
                        "  \"merchant_order_no\": \"BB-20300101-001\",\n" +
                        "  \"currency\": \"AUD\",\n" +
                        "  \"trans_func\": 3,\n" +
                        "  \"first_name\": \"Emily\",\n" +
                        "  \"last_name\": \"Carter\",\n" +
                        "  \"card\": {\n" +
                        "    \"card_number\": \"4111111111111111\",\n" +
                        "    \"expiration_month\": \"12\",\n" +
                        "    \"expiration_year\": \"2030\",\n" +
                        "    \"security_code\": \"123\"\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: Existing customer token payment
          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/trans/directPay";
                    String payload =
                        "{\n" +
                        "  \"merchant_id\": \"48290713\",\n" +
                        "  \"amount\": \"25.50\",\n" +
                        "  \"merchant_order_no\": \"BB-20300101-002\",\n" +
                        "  \"currency\": \"AUD\",\n" +
                        "  \"trans_func\": 2,\n" +
                        "  \"customer_id\": \"CUS48290713\",\n" +
                        "  \"card_token\": \"4a9c8e71d6b24f03a58d19c7e2046b35\",\n" +
                        "  \"first_name\": \"Emily\",\n" +
                        "  \"last_name\": \"Carter\"\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: Create a token without charging
          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/trans/directPay";
                    String payload =
                        "{\n" +
                        "  \"merchant_id\": \"48290713\",\n" +
                        "  \"amount\": \"25.50\",\n" +
                        "  \"merchant_order_no\": \"BB-20300101-003\",\n" +
                        "  \"currency\": \"AUD\",\n" +
                        "  \"trans_func\": 1,\n" +
                        "  \"first_name\": \"Emily\",\n" +
                        "  \"last_name\": \"Carter\",\n" +
                        "  \"card\": {\n" +
                        "    \"card_number\": \"4111111111111111\",\n" +
                        "    \"expiration_month\": \"12\",\n" +
                        "    \"expiration_year\": \"2030\",\n" +
                        "    \"security_code\": \"123\"\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: Create a checkout session
          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/trans/directPay";
                    String payload =
                        "{\n" +
                        "  \"merchant_id\": \"48290713\",\n" +
                        "  \"amount\": \"25.50\",\n" +
                        "  \"merchant_order_no\": \"BB-20300101-004\",\n" +
                        "  \"currency\": \"AUD\",\n" +
                        "  \"trans_func\": 4,\n" +
                        "  \"return_url\": \"https://portal.example.com/payments/complete\"\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: Scheduled bank account payment
          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/trans/directPay";
                    String payload =
                        "{\n" +
                        "  \"merchant_id\": \"48290713\",\n" +
                        "  \"amount\": \"25.50\",\n" +
                        "  \"merchant_order_no\": \"BB-20300101-005\",\n" +
                        "  \"currency\": \"AUD\",\n" +
                        "  \"trans_func\": 5,\n" +
                        "  \"bank_account\": {\n" +
                        "    \"bsb\": \"062-000\",\n" +
                        "    \"account_no\": \"618472950\",\n" +
                        "    \"account_name\": \"Emily Carter\"\n" +
                        "  },\n" +
                        "  \"process_date\": \"2030-01-15\"\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: Card payment with 3DS
          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/trans/directPay";
                    String payload =
                        "{\n" +
                        "  \"merchant_id\": \"48290713\",\n" +
                        "  \"amount\": \"25.50\",\n" +
                        "  \"merchant_order_no\": \"BB-20300101-006\",\n" +
                        "  \"currency\": \"AUD\",\n" +
                        "  \"trans_func\": 3,\n" +
                        "  \"first_name\": \"Emily\",\n" +
                        "  \"last_name\": \"Carter\",\n" +
                        "  \"card\": {\n" +
                        "    \"card_number\": \"4111111111111111\",\n" +
                        "    \"expiration_month\": \"12\",\n" +
                        "    \"expiration_year\": \"2030\",\n" +
                        "    \"security_code\": \"123\"\n" +
                        "  },\n" +
                        "  \"is3ds\": 1,\n" +
                        "  \"return_url\": \"https://portal.example.com/payments/complete\"\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: Scheduled card payment
          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/trans/directPay";
                    String payload =
                        "{\n" +
                        "  \"merchant_id\": \"48290713\",\n" +
                        "  \"amount\": \"25.50\",\n" +
                        "  \"merchant_order_no\": \"BB-20300101-007\",\n" +
                        "  \"currency\": \"AUD\",\n" +
                        "  \"trans_func\": 3,\n" +
                        "  \"first_name\": \"Emily\",\n" +
                        "  \"last_name\": \"Carter\",\n" +
                        "  \"card\": {\n" +
                        "    \"card_number\": \"4111111111111111\",\n" +
                        "    \"expiration_month\": \"12\",\n" +
                        "    \"expiration_year\": \"2030\",\n" +
                        "    \"security_code\": \"123\"\n" +
                        "  },\n" +
                        "  \"process_date\": \"2030-01-15\"\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: Immediate card payment
          source: |
            require "net/http"
            require "uri"

            base_url = ENV.fetch("BASE_URL").sub(%r{/+$}, "")
            uri = URI(base_url + "/api/v2/trans/directPay")
            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",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-001",
              "currency": "AUD",
              "trans_func": 3,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              },
              "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: Existing customer token payment
          source: |
            require "net/http"
            require "uri"

            base_url = ENV.fetch("BASE_URL").sub(%r{/+$}, "")
            uri = URI(base_url + "/api/v2/trans/directPay")
            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",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-002",
              "currency": "AUD",
              "trans_func": 2,
              "customer_id": "CUS48290713",
              "card_token": "4a9c8e71d6b24f03a58d19c7e2046b35",
              "first_name": "Emily",
              "last_name": "Carter"
            }
            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: Create a token without charging
          source: |
            require "net/http"
            require "uri"

            base_url = ENV.fetch("BASE_URL").sub(%r{/+$}, "")
            uri = URI(base_url + "/api/v2/trans/directPay")
            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",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-003",
              "currency": "AUD",
              "trans_func": 1,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              }
            }
            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: Create a checkout session
          source: |
            require "net/http"
            require "uri"

            base_url = ENV.fetch("BASE_URL").sub(%r{/+$}, "")
            uri = URI(base_url + "/api/v2/trans/directPay")
            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",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-004",
              "currency": "AUD",
              "trans_func": 4,
              "return_url": "https://portal.example.com/payments/complete"
            }
            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: Scheduled bank account payment
          source: |
            require "net/http"
            require "uri"

            base_url = ENV.fetch("BASE_URL").sub(%r{/+$}, "")
            uri = URI(base_url + "/api/v2/trans/directPay")
            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",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-005",
              "currency": "AUD",
              "trans_func": 5,
              "bank_account": {
                "bsb": "062-000",
                "account_no": "618472950",
                "account_name": "Emily Carter"
              },
              "process_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: Card payment with 3DS
          source: |
            require "net/http"
            require "uri"

            base_url = ENV.fetch("BASE_URL").sub(%r{/+$}, "")
            uri = URI(base_url + "/api/v2/trans/directPay")
            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",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-006",
              "currency": "AUD",
              "trans_func": 3,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              },
              "is3ds": 1,
              "return_url": "https://portal.example.com/payments/complete"
            }
            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: Scheduled card payment
          source: |
            require "net/http"
            require "uri"

            base_url = ENV.fetch("BASE_URL").sub(%r{/+$}, "")
            uri = URI(base_url + "/api/v2/trans/directPay")
            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",
              "amount": "25.50",
              "merchant_order_no": "BB-20300101-007",
              "currency": "AUD",
              "trans_func": 3,
              "first_name": "Emily",
              "last_name": "Carter",
              "card": {
                "card_number": "4111111111111111",
                "expiration_month": "12",
                "expiration_year": "2030",
                "security_code": "123"
              },
              "process_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
components:
  schemas:
    DirectPayRequest:
      type: object
      description: >-
        Payment request. Omitting both customer identifiers selects no-customer
        mode. If both customer_id and external_customer_id are provided,
        customer_id takes precedence. Only Visa/Mastercard/Amex cards are
        supported. Amount, name and card field requirements still apply to
        existing customers. Only operations 2/3/5 can be scheduled.
      properties:
        trans_func:
          type: integer
          description: >-
            Transaction operation: 1 create a token without charging; 2 token
            payment; 3 card payment; 4 create a checkout session; 5 bank account
            payment.
          enum:
            - 1
            - 2
            - 3
            - 4
            - 5
        merchant_id:
          type: string
          description: Business identifier assigned by BillBuddy.
          maxLength: 20
          minLength: 1
        amount:
          oneOf:
            - type: number
              multipleOf: 0.01
              minimum: 0.01
              maximum: 999999.99
            - type: string
              pattern: ^\d+(\.\d{1,2})?$
              allOf:
                - pattern: ^0*(?:[1-9]\d{0,5}(?:\.\d{1,2})?|0\.(?:0[1-9]|[1-9]\d?))$
          description: >-
            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 999999.99; the same
            range applies to both types.
        merchant_order_no:
          type: string
          description: >-
            Merchant order number. Must be unique within the same merchant. A
            duplicate request does not return an existing successful order.
          maxLength: 60
          minLength: 1
        currency:
          type: string
          description: >-
            Currency code, such as AUD. Currency support also depends on the
            merchant's payment channel configuration.
          minLength: 3
          maxLength: 3
        card:
          type: object
          description: Credit card information.
          properties:
            card_number:
              type: string
              description: >-
                Visa, Mastercard or American Express card number. Acceptance
                depends on card brand recognition and channel configuration.
                Ignored for trans_func=2. Required and non-null for trans_func=1
                or 3. Supply valid card details; the actual response determines
                the payment outcome.
              maxLength: 20
            expiration_month:
              type: string
              description: >-
                Card expiry month, preferably two digits, such as 12. Ignored
                for trans_func=2. Required and non-null for trans_func=1 or 3.
                Supply valid card details; the actual response determines the
                payment outcome.
              minLength: 2
              maxLength: 2
            expiration_year:
              type: string
              description: >-
                Card expiry year, preferably four digits, such as 2030. Ignored
                for trans_func=2. Required and non-null for trans_func=1 or 3.
                Supply valid card details; the actual response determines the
                payment outcome.
              minLength: 4
              maxLength: 4
            security_code:
              type: string
              description: >-
                Card security code (CVV). Use a string to preserve leading
                zeros. Ignored for trans_func=2. Required and non-null for
                trans_func=1 or 3. Supply valid card details; the actual
                response determines the payment outcome.
              maxLength: 4
        card_token:
          type: string
          description: >-
            Payment token returned by BillBuddy. When a customer is supplied,
            the token must belong to that customer. Required for trans_func=2.
          nullable: true
          maxLength: 255
        first_name:
          type: string
          description: First name. Required for trans_func=1/2/3.
          nullable: true
          maxLength: 50
        last_name:
          type: string
          description: Last name. Required for trans_func=1/2/3.
          nullable: true
          maxLength: 50
        email:
          type: string
          description: Email address.
          nullable: true
          format: email
          maxLength: 100
        phone:
          type: string
          description: Contact phone number.
          nullable: true
          maxLength: 50
        address:
          type: string
          description: Street address.
          nullable: true
          maxLength: 100
        city:
          type: string
          description: City.
          nullable: true
          maxLength: 50
        state:
          type: string
          description: State or province.
          nullable: true
          maxLength: 100
        postcode:
          type: string
          description: Postcode.
          nullable: true
          maxLength: 4
        country_iso2:
          type: string
          description: Two-letter country code, such as AU.
          nullable: true
          minLength: 2
          maxLength: 2
        is3ds:
          type: integer
          description: >-
            Whether to use 3DS: 0 disabled, 1 enabled; omission means 0. Bank
            account payments do not perform 3DS. Whether to display an
            authentication page depends on response data.html.
          nullable: true
          enum:
            - 1
            - 0
            - null
          default: 0
        return_url:
          type: string
          description: >-
            Return URL after 3DS authentication or checkout completion. Required
            when is3ds=1 or trans_func=4. Provide a valid return URL; see the
            schema for its length limit.
          nullable: true
          maxLength: 255
        customer_id:
          type: string
          description: >-
            BillBuddy customer identifier. Must identify a valid customer within
            the current merchant and business.
          nullable: true
          maxLength: 32
        external_customer_id:
          type: string
          description: >-
            Customer reference in the merchant system. Used to find the customer
            when customer_id is omitted. If both identifiers are provided,
            customer_id takes precedence.
          nullable: true
          maxLength: 64
        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'
        bank_account:
          type: object
          description: Bank account information.
          properties:
            bsb:
              type: string
              description: >-
                Required for trans_func=5. Supply a valid six-digit BSB. Spaces
                and hyphens are permitted and excluded from the six-character
                length.
              nullable: true
              pattern: ^(?:[\s-]*[^\s-]){6}[\s-]*$
            account_no:
              type: string
              description: >-
                Required for trans_func=5. Supply a valid bank account number as
                a string to preserve leading zeros. Spaces and hyphens are
                permitted. After removing these separators, the value must
                contain 1 to 9 characters and cannot consist solely of
                separators.
              nullable: true
              pattern: ^(?:[\s-]*[^\s-]){0,9}[\s-]*$
            account_name:
              type: string
              description: >-
                Bank account holder name. Required and non-null when
                trans_func=5.
              nullable: true
              maxLength: 100
        process_date:
          type: string
          description: >-
            Scheduled processing date in YYYY-MM-DD format. Must be strictly
            after today in the service business timezone. Supported only for
            trans_func=2/3/5 and cannot be combined with is3ds=1. YYYY-MM-DD is
            recommended. Must be later than today in the service business
            timezone.
          nullable: true
          format: date
      required:
        - trans_func
        - merchant_id
        - amount
        - merchant_order_no
        - currency
      not:
        anyOf:
          - allOf:
              - required:
                  - trans_func
                properties:
                  trans_func:
                    enum:
                      - 2
              - not:
                  required:
                    - card_token
                    - first_name
                    - last_name
                  properties:
                    card_token:
                      not:
                        enum:
                          - null
                      minLength: 1
                    first_name:
                      not:
                        enum:
                          - null
                      minLength: 1
                    last_name:
                      not:
                        enum:
                          - null
                      minLength: 1
          - allOf:
              - required:
                  - trans_func
                properties:
                  trans_func:
                    enum:
                      - 3
              - not:
                  required:
                    - card
                    - first_name
                    - last_name
                  properties:
                    card:
                      not:
                        enum:
                          - null
                    first_name:
                      not:
                        enum:
                          - null
                      minLength: 1
                    last_name:
                      not:
                        enum:
                          - null
                      minLength: 1
          - allOf:
              - required:
                  - trans_func
                properties:
                  trans_func:
                    enum:
                      - 5
              - not:
                  required:
                    - bank_account
                  properties:
                    bank_account:
                      not:
                        enum:
                          - null
          - allOf:
              - required:
                  - trans_func
                properties:
                  trans_func:
                    enum:
                      - 1
              - not:
                  required:
                    - card
                    - first_name
                    - last_name
                  properties:
                    card:
                      not:
                        enum:
                          - null
                    first_name:
                      not:
                        enum:
                          - null
                      minLength: 1
                    last_name:
                      not:
                        enum:
                          - null
                      minLength: 1
          - allOf:
              - required:
                  - trans_func
                properties:
                  trans_func:
                    enum:
                      - 4
              - not:
                  required:
                    - return_url
                  properties:
                    return_url:
                      not:
                        enum:
                          - null
                      minLength: 1
          - allOf:
              - required:
                  - is3ds
                properties:
                  is3ds:
                    enum:
                      - 1
              - not:
                  required:
                    - return_url
                  properties:
                    return_url:
                      not:
                        enum:
                          - null
                      minLength: 1
          - allOf:
              - required:
                  - trans_func
                properties:
                  trans_func:
                    enum:
                      - 1
                      - 3
              - not:
                  required:
                    - card
                  properties:
                    card:
                      not:
                        enum:
                          - null
                      minProperties: 1
                      required:
                        - card_number
                        - expiration_month
                        - expiration_year
                        - security_code
                      properties:
                        card_number:
                          not:
                            enum:
                              - null
                          minLength: 1
                        expiration_month:
                          not:
                            enum:
                              - null
                          minLength: 1
                        expiration_year:
                          not:
                            enum:
                              - null
                          minLength: 1
                        security_code:
                          not:
                            enum:
                              - null
                          minLength: 1
          - allOf:
              - required:
                  - trans_func
                properties:
                  trans_func:
                    enum:
                      - 5
              - not:
                  required:
                    - bank_account
                  properties:
                    bank_account:
                      not:
                        enum:
                          - null
                      minProperties: 1
                      required:
                        - bsb
                        - account_no
                        - account_name
                      properties:
                        bsb:
                          not:
                            enum:
                              - null
                          minLength: 1
                        account_no:
                          not:
                            enum:
                              - null
                          minLength: 1
                          pattern: '[^\s-]'
                        account_name:
                          not:
                            enum:
                              - null
                          minLength: 1
          - allOf:
              - required:
                  - trans_func
                properties:
                  trans_func:
                    enum:
                      - 2
              - not:
                  required:
                    - card_token
                    - first_name
                    - last_name
                  properties:
                    card_token:
                      not:
                        enum:
                          - null
                      minLength: 1
                    first_name:
                      not:
                        enum:
                          - null
                      minLength: 1
                    last_name:
                      not:
                        enum:
                          - null
                      minLength: 1
          - allOf:
              - required:
                  - trans_func
                properties:
                  trans_func:
                    enum:
                      - 1
                      - 3
              - not:
                  required:
                    - first_name
                    - last_name
                  properties:
                    first_name:
                      not:
                        enum:
                          - null
                      minLength: 1
                    last_name:
                      not:
                        enum:
                          - null
                      minLength: 1
          - allOf:
              - required:
                  - trans_func
                properties:
                  trans_func:
                    enum:
                      - 4
              - not:
                  required:
                    - return_url
                  properties:
                    return_url:
                      not:
                        enum:
                          - null
                      minLength: 1
          - allOf:
              - required:
                  - is3ds
                properties:
                  is3ds:
                    enum:
                      - 1
              - not:
                  required:
                    - return_url
                  properties:
                    return_url:
                      not:
                        enum:
                          - null
                      minLength: 1
          - allOf:
              - required:
                  - trans_func
                properties:
                  trans_func:
                    enum:
                      - 5
              - required:
                  - card
                properties:
                  card:
                    type: object
                    minProperties: 1
          - allOf:
              - required:
                  - process_date
                properties:
                  process_date:
                    type: string
                    minLength: 1
              - not:
                  properties:
                    trans_func:
                      enum:
                        - 2
                        - 3
                        - 5
                    is3ds:
                      not:
                        enum:
                          - 1
    DirectPayResponse:
      type: object
      description: Success response.
      properties:
        code:
          type: integer
          description: >-
            0 means the API request was processed successfully. Token creation,
            checkout, 3DS and Pending results do not indicate a completed
            charge; assess data as well.
          enum:
            - 0
        message:
          type: string
          description: Response message.
        data:
          oneOf:
            - $ref: '#/components/schemas/DirectPayData'
            - $ref: '#/components/schemas/CheckoutData'
          description: >-
            Payment data or checkout session, depending on the transaction
            operation.
      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
    DirectPayData:
      type: object
      description: Result of a payment, token creation, 3DS or scheduled request.
      properties:
        business_id:
          type: string
          description: Merchant identifier assigned by BillBuddy.
        merchant_id:
          type: string
          description: Business identifier assigned by BillBuddy.
        order_number:
          type: string
          description: >-
            BillBuddy transaction number. Token creation returns an operation
            number. May be an empty string while waiting for customer 3DS
            authentication.
        merchant_order_no:
          type: string
          description: Merchant order number.
        trans_func:
          type: integer
          description: 'Transaction operation: 1/2/3/5.'
          enum:
            - 1
            - 2
            - 3
            - 5
        complete_date:
          type: string
          description: >-
            Response generation or transaction creation time in DD/MM/YYYY
            HH:mm:ss format. Does not indicate completed funds processing.
        currency:
          type: string
          description: Currency code.
        amount:
          oneOf:
            - type: number
              multipleOf: 0.01
            - type: string
              pattern: ^\d+(\.\d{1,2})?$
          description: >-
            Amount in major currency units with at most two decimal places,
            returned as a number or decimal string. For a created transaction,
            this is the payment amount and may include applicable fees. For
            token creation or pending 3DS, it is the requested amount and does
            not indicate a charge.
        html:
          type: string
          description: HTML page/form for 3DS when required. Usually an empty string.
        card_token:
          type: string
          description: >-
            Payment token on successful token creation; echoes the requested
            token for token payments. Usually an empty string for card and bank
            payments.
        status:
          type: integer
          description: >-
            Transaction status: 1 Successful; 2 Failed; 3 Pending; 4 Expired.
            Pending means accepted or processing and must not be treated as
            successful collection of funds.
          enum:
            - 1
            - 2
            - 3
            - 4
        code:
          oneOf:
            - type: integer
            - type: string
          description: >-
            Transaction result code, distinct from top-level response code.
            Defaults to 0.
        remark:
          type: string
          description: Transaction or channel result description. May be an empty string.
        sign_type:
          type: string
          description: 'Signature type: SHA256.'
          enum:
            - SHA256
        sign:
          type: string
          description: >-
            Response signature as a lowercase SHA256 hexadecimal digest.
            Examples are calculated offline according to the signing rules for
            the corresponding payment scenario, using the public demo key
            bb_docs_demo_signing_key_2030. The html field is excluded for
            responses awaiting 3DS authentication. This is not an OAuth
            credential.
        process_date:
          type: string
          description: Returned only for scheduled requests, in YYYY-MM-DD format.
          format: date
        cancel_deadline:
          type: string
          description: >-
            Returned only for scheduled requests. The cancellation cutoff is
            08:15:00 Australia/Sydney on the processing date; cancellation is
            not permitted at or after this time. Format: YYYY-MM-DD HH:mm:ss.
      required:
        - business_id
        - merchant_id
        - order_number
        - merchant_order_no
        - trans_func
        - complete_date
        - currency
        - amount
        - html
        - card_token
        - status
        - code
        - remark
        - sign_type
        - sign
    CheckoutData:
      type: object
      description: Returned when trans_func=4.
      properties:
        checkout_url:
          type: string
          description: Complete customer checkout URL.
          format: uri
        expires_at:
          type: string
          description: >-
            Session expiry in DD/MM/YYYY HH:mm:ss format, usually 30 minutes
            after creation.
      required:
        - checkout_url
        - expires_at
  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.