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

# Cancel a Payment Link

> Permanently cancel an active payment link by ID

<Warning>
  Cancellation is permanent. Cancelled links cannot be reactivated — create a new link to accept payments again. Only `ACTIVE` links can be cancelled.
</Warning>

Returns the cancelled payment link with `status: "CANCELLED"`, `cancelled_at` populated, and `cancellation_reason` if a `reason` was provided.

## Idempotency

An `Idempotency-Key` header is optional here — cancel is idempotent by nature, so re-cancelling an already-cancelled link is a safe no-op. If you do send one, use a unique client-generated identifier (letters, digits, dot, hyphen, underscore; 8–64 characters). The optional `reason` is stored for audit purposes.

## Required scope

`payment_links.cancel`


## OpenAPI

````yaml api-reference/ecom/openapi.json POST /checkout/{id}/cancel
openapi: 3.0.3
info:
  title: Ecom API
  description: >-
    REST API for creating and managing hosted payment links (checkout). Generate
    a shareable, hosted checkout URL, accept one-time or multi-use payments, and
    reconcile results through webhooks.


    **Entity scoping:** Every API key is scoped to an entity in the organization
    hierarchy (Partner → Merchant → Branch). Data access is automatically
    restricted to the key's level.


    **Amounts:** All monetary values are integers in the smallest currency unit
    (centavos for PHP). `150000` represents PHP 1,500.00.


    **Idempotency:** Mutating `POST` requests require an `Idempotency-Key`
    header to safely retry without creating duplicates.
  version: 1.0.0
  contact:
    name: API Support
    email: support@moduluslabs.io
  license:
    name: Proprietary
servers:
  - url: https://api.sbx.moduluslabs.io/ecom/v1
    description: Sandbox
security:
  - BearerAuth: []
tags:
  - name: Payment Links
    description: Create and manage hosted payment links
paths:
  /checkout/{id}/cancel:
    parameters:
      - $ref: '#/components/parameters/PaymentLinkId'
    post:
      tags:
        - Payment Links
      summary: Cancel a payment link
      description: >-
        Permanently cancels an active payment link. Cancelled links cannot be
        reactivated — create a new link to accept payments again. Only `ACTIVE`
        links can be cancelled.


        Requires the `payment_links.cancel` scope.
      operationId: cancelPaymentLink
      parameters:
        - name: Idempotency-Key
          in: header
          required: false
          description: >-
            Optional. Cancel is idempotent by nature — re-cancelling an
            already-cancelled link is a safe no-op — so a key is accepted but
            not required. Same charset as create: letters, digits, dot (`.`),
            hyphen (`-`), underscore (`_`); 8–64 characters.
          schema:
            type: string
            pattern: ^[A-Za-z0-9._-]{8,64}$
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CancelPaymentLinkRequest'
            example:
              reason: Customer requested cancellation
      responses:
        '200':
          description: The cancelled payment link
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentLinkResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/InvalidState'
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  parameters:
    PaymentLinkId:
      name: id
      in: path
      required: true
      description: The payment link ID (UUID v4).
      schema:
        type: string
        format: uuid
  schemas:
    CancelPaymentLinkRequest:
      type: object
      properties:
        reason:
          type: string
          maxLength: 500
          description: Why the link is being cancelled. Stored for audit purposes.
          example: Customer requested cancellation
    PaymentLinkResponse:
      type: object
      required:
        - data
      properties:
        data:
          $ref: '#/components/schemas/PaymentLink'
    PaymentLink:
      type: object
      description: The payment link object returned by all endpoints.
      required:
        - id
        - type
        - merchant_branch_reference_number
        - merchant_branch_name
        - currency
        - amount
        - line_items
        - status
        - expires_at
        - hosted_url
        - successful_payment_count
        - metadata
        - created_at
        - updated_at
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID v4). Use this in API paths and for tracking.
          example: 550e8400-e29b-41d4-a716-446655440000
        type:
          $ref: '#/components/schemas/PaymentLinkType'
        merchant_branch_reference_number:
          type: string
          description: Reference number of the branch this link belongs to.
          example: SH-ANG-001
        merchant_branch_name:
          type: string
          description: Display name of the branch. Read-only.
          example: SM City Angeles - Branch 1
        currency:
          type: string
          description: ISO 4217 currency code.
          example: PHP
        amount:
          type: integer
          format: int64
          description: >-
            Payment amount in the smallest currency unit (centavos for PHP).
            `150000` = PHP 1,500.00.
          example: 150000
        line_items:
          type: array
          description: Items the customer is paying for.
          items:
            $ref: '#/components/schemas/LineItem'
        description:
          type: string
          nullable: true
          description: Merchant-defined description displayed to the customer.
          example: Order for wireless earbuds
        order_reference:
          type: string
          nullable: true
          maxLength: 100
          description: Merchant's internal order reference for reconciliation.
          example: ORD-2026-0618-001
        redirect_urls:
          allOf:
            - $ref: '#/components/schemas/RedirectUrls'
          nullable: true
        status:
          $ref: '#/components/schemas/PaymentLinkStatus'
        expires_at:
          type: string
          format: date-time
          description: ISO 8601 timestamp. When the link stops accepting payments.
          example: '2026-07-18T00:00:00Z'
        hosted_url:
          type: string
          format: uri
          description: The URL to share with customers. Read-only.
          example: >-
            https://pay.moduluslabs.io/checkout/550e8400-e29b-41d4-a716-446655440000
        max_uses:
          type: integer
          nullable: true
          description: >-
            Maximum number of successful payments allowed. `null` = unlimited.
            Only applicable for `multi_use` links.
          example: 10
        successful_payment_count:
          type: integer
          description: Number of successful payments completed so far.
          example: 3
        metadata:
          type: object
          description: >-
            Merchant key-value pairs. Max 50 keys, key max 40 characters, value
            max 500 characters.
          additionalProperties:
            type: string
        created_at:
          type: string
          format: date-time
          description: ISO 8601 timestamp. When the link was created.
          example: '2026-06-18T10:30:00Z'
        updated_at:
          type: string
          format: date-time
          description: ISO 8601 timestamp. When the link was last modified.
          example: '2026-06-18T14:22:00Z'
        cancelled_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            ISO 8601 timestamp. When the link was cancelled. `null` if not
            cancelled.
        cancellation_reason:
          type: string
          nullable: true
          maxLength: 500
          description: Reason for cancellation. `null` if not cancelled.
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: Machine-readable error code.
              example: invalid_request
            message:
              type: string
              description: Human-readable explanation of the error.
              example: Amount must be greater than zero.
            correlationId:
              type: string
              format: uuid
              description: Unique request identifier. Include this in support requests.
              example: a084e7ab-e80e-4232-b6b7-280167765883
    PaymentLinkType:
      type: string
      description: >-
        `one_time` accepts exactly one successful payment then becomes
        `CONSUMED`. `multi_use` accepts multiple payments, optionally up to
        `max_uses`.
      enum:
        - one_time
        - multi_use
    LineItem:
      type: object
      required:
        - sku
        - name
        - unit_price
        - quantity
      properties:
        sku:
          type: string
          description: Merchant-defined SKU or product identifier.
          example: PROD-001
        name:
          type: string
          description: Product name displayed to the customer.
          example: Wireless Earbuds
        unit_price:
          type: integer
          format: int64
          minimum: 1
          description: >-
            Price per unit in the smallest currency unit. Must be greater than
            0.
          example: 75000
        quantity:
          type: integer
          minimum: 1
          description: Number of units. Must be greater than 0.
          example: 2
        metadata:
          type: object
          description: Optional key-value pairs for this line item.
          additionalProperties:
            type: string
    RedirectUrls:
      type: object
      description: URLs to redirect the customer after payment. Each URL must use HTTPS.
      properties:
        success:
          type: string
          format: uri
          description: URL to redirect after a successful payment.
          example: https://merchant.com/payment/success
        declined:
          type: string
          format: uri
          description: URL to redirect after a declined payment.
          example: https://merchant.com/payment/declined
        expired:
          type: string
          format: uri
          description: URL to redirect when the payment link has expired.
          example: https://merchant.com/payment/expired
    PaymentLinkStatus:
      type: string
      description: Current status of the payment link.
      enum:
        - ACTIVE
        - CONSUMED
        - EXPIRED
        - CANCELLED
  responses:
    BadRequest:
      description: The request body or parameters failed validation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            invalid_request:
              summary: Validation failed
              value:
                error:
                  code: invalid_request
                  message: Amount must equal the sum of all line items.
                  correlationId: a084e7ab-e80e-4232-b6b7-280167765883
            idempotency_key_required:
              summary: Missing Idempotency-Key header
              value:
                error:
                  code: idempotency_key_required
                  message: The Idempotency-Key header is required for this request.
                  correlationId: a084e7ab-e80e-4232-b6b7-280167765883
    Unauthorized:
      description: The API key is missing, expired, revoked, or invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: invalid_api_key
              message: API key is missing or invalid.
              correlationId: a084e7ab-e80e-4232-b6b7-280167765883
    Forbidden:
      description: The API key does not have the required scope for this operation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: insufficient_permissions
              message: API key lacks the required scope for this operation.
              correlationId: a084e7ab-e80e-4232-b6b7-280167765883
    NotFound:
      description: The requested resource does not exist or is not accessible by your key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: not_found
              message: The requested payment link does not exist.
              correlationId: a084e7ab-e80e-4232-b6b7-280167765883
    InvalidState:
      description: >-
        The operation is not allowed in the current status (e.g., the link is
        already cancelled, expired, or consumed).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: invalid_state
              message: Only ACTIVE payment links can be modified.
              correlationId: a084e7ab-e80e-4232-b6b7-280167765883
    RateLimited:
      description: >-
        Too many requests. Retry after the time indicated in the `Retry-After`
        header.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: rate_limited
              message: Rate limit exceeded. Retry after 23 seconds.
              correlationId: a084e7ab-e80e-4232-b6b7-280167765883
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        API key passed as a bearer token. Use `sk_live_` keys for production and
        `sk_test_` keys for sandbox. Keys are provisioned during merchant
        onboarding.

````