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

> ## Agent Instructions
> Use hosted checkout for a new payment integration unless the user explicitly needs an SDK or Direct QR flow.
> Keep secret API keys on the server. Never place an sk_test_ or sk_live_ key in browser or mobile code.
> Never treat a browser return URL as proof of payment. Verify a signed webhook and confirm status, amount, and currency on the server before fulfillment.
> Fonepay has no sandbox. A Fonepay payment made from a sandbox project uses the merchant's real Fonepay account and moves real money within the documented caps.
> Do not recommend direct integration with Mobile SDK device endpoints. Use the PayBridgeNP Mobile SDK and the merchant-facing session creation API.

# Update a coupon

> Only `{ active: false }` is supported; discount parameters are immutable. Deactivating stops future redemptions.



## OpenAPI

````yaml PATCH /v1/billing/coupons/{id}
openapi: 3.1.0
info:
  title: PayBridgeNP API
  version: 1.0.0
  description: >-
    PayBridgeNP is Nepal's payment gateway - accept eSewa, Khalti, and Fonepay
    through a single API.


    **Base URL:** `https://api.paybridgenp.com`


    **Dashboard:**
    [dashboard.paybridgenp.com](https://dashboard.paybridgenp.com)


    All monetary amounts are in **paisa** (1 NPR = 100 paisa). An amount of
    `10000` represents Rs. 100.00.
  contact:
    name: PayBridgeNP Support
    url: https://paybridgenp.com
servers:
  - url: https://api.paybridgenp.com
    description: Production
security:
  - BearerAuth: []
tags:
  - name: Authentication
    description: >-
      ## API Keys


      All merchant-facing API endpoints require a Bearer API key in the
      `Authorization` header:


      ```

      Authorization: Bearer sk_live_your_api_key_here

      ```


      You can find and rotate your API keys in the [PayBridgeNP
      Dashboard](https://dashboard.paybridgenp.com) under **Settings → API
      Keys**.


      ### Key prefixes


      | Prefix | Mode | Use |

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

      | `sk_test_` | Sandbox | eSewa and Khalti test flows; see the Fonepay
      warning below |

      | `sk_live_` | Live | Production - real payments |


      The mode is fixed per key. A sandbox key creates sandbox records; a live
      key creates live payments. **Never expose a secret key in client-side
      code.**
  - name: Sandbox & Live Modes
    description: >-
      ## Sandbox Mode


      Sandbox mode lets you test eSewa and Khalti without real money. To use
      sandbox mode:


      1. Generate a sandbox key (`sk_test_...`) from the dashboard.

      2. Use it exactly like a live key - the API behaves identically.

      3. On the hosted checkout page, use the built-in test credentials below.


      ### Built-in test credentials


      | Provider | Test credential |

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

      | eSewa | ID `9806800001`, password `Nepal@123`, MPIN `1122`, OTP `123456`
      |

      | Khalti | Phone `9800000001`, MPIN `1111`, OTP `987654` |


      Sandbox payments appear in your dashboard under the **Sandbox** tab.


      **Fonepay has no sandbox.** If you enable Fonepay on a sandbox project,
      PayBridgeNP uses your real Fonepay merchant account and the payment moves
      real money. Sandbox Fonepay is capped at NPR 1,000 per payment and NPR
      5,000 per month. Use a small amount such as NPR 10.


      ### Switching to live


      Configure your live provider credentials, replace the `sk_test_` key with
      a `sk_live_` key, and run the go-live checks before accepting customers.
  - name: Errors
    description: >-
      ## Error Responses


      All errors return a single nested envelope:


      ```json

      {
        "error": {
          "message": "amount must be a positive integer (in paisa)",
          "type": "invalid_request_error",
          "code": "invalid_request_error",
          "request_id": "req_2Je91NlWKuXkdXUJOK9gaHNW"
        }
      }

      ```


      Read `error.message` for the human-readable string, `error.type` for the
      broad category (SDKs map it to a typed exception), `error.code` to branch
      on, and `error.request_id` (matches `X-Request-Id`) when contacting
      support.


      ### HTTP status codes


      | Status | Meaning |

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

      | `400` | Bad request - check the `error` field for details |

      | `401` | Unauthorized - missing or invalid API key |

      | `404` | Resource not found |

      | `409` | Conflict - e.g. concurrent idempotent request, customer has
      active subscriptions |

      | `422` | Unprocessable - business logic violation |

      | `429` | Rate limit exceeded - back off and retry |

      | `500` | Internal server error |


      ### Common error types and codes


      | `error.type` | Example `error.code` | Meaning |

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

      | `authentication_error` | `api_key_invalid` | Missing or invalid API key
      |

      | `invalid_request_error` | `not_found` | Validation failure, or the
      resource does not exist or belongs to another project |

      | `idempotency_error` | `idempotency_conflict` | Two concurrent requests
      sent the same `Idempotency-Key` |

      | `rate_limit_error` | `rate_limited` | Rate-limit window exhausted |

      | `api_error` | `api_error` | Server-side failure - safe to retry |


      For the full list of `type` and `code` values, see the [Errors
      reference](https://docs.paybridgenp.com/api-reference/errors).
  - name: Payments
  - name: Refunds
  - name: Webhooks
  - name: Billing
  - name: Account
  - name: Sessions
    description: Read-only access to the checkout sessions created via `POST /v1/checkout`.
  - name: Payment Links
    description: Create and manage reusable hosted payment pages through the API.
  - name: Analytics
    description: >-
      Aggregated KPIs for the authenticated project - payment totals, success
      rate, provider breakdown, and the checkout funnel.
  - name: Providers
    description: >-
      Lists the payment providers enabled and configured for the authenticated
      project, so an integrator can decide which "Pay with X" options to render.
  - name: QR
    description: >-
      Direct-QR API for Fonepay - mint a Dynamic QR server-side and listen for
      scan/pay events over SSE, bypassing the hosted checkout page. Pro.
  - name: SMS
    description: >-
      Send transactional SMS on the merchant's behalf with the merchant's plan
      limits, audit trail, and anti-abuse guards applied. Live SMS is
      plan-metered: Free 0/month, Growth 200/month, Pro 1,000/month (sandbox is
      always logged, never delivered).
  - name: Mobile
    description: >-
      Native mobile SDK endpoints. Create a checkout session that returns
      provider native-SDK params, then verify the result after the native flow
      completes.
  - name: Public
paths:
  /v1/billing/coupons/{id}:
    patch:
      tags:
        - Billing
      summary: Update a coupon
      description: >-
        Only `{ active: false }` is supported; discount parameters are
        immutable. Deactivating stops future redemptions.
      operationId: updateCoupon
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - active
              properties:
                active:
                  type: boolean
                  enum:
                    - false
      responses:
        '200':
          description: Coupon updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Coupon'
        '400':
          description: 'Only { active: false } is supported.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    Coupon:
      type: object
      properties:
        id:
          type: string
          example: cpn_01j9x2k3m4n5p6q7r8s9t0u1v2
        object:
          type: string
          enum:
            - coupon
        code:
          type: string
          example: WELCOME10
        name:
          type: string
          example: Welcome 10%
        discount_type:
          type: string
          enum:
            - percent
            - amount
        percent_off:
          type: integer
          nullable: true
          description: Percent discount (1–100), when discount_type is `percent`.
          example: 10
        amount_off:
          type: integer
          nullable: true
          description: Fixed discount in paisa, when discount_type is `amount`.
        currency:
          type: string
          example: NPR
        duration:
          type: string
          enum:
            - once
            - repeating
            - forever
        duration_in_cycles:
          type: integer
          nullable: true
          description: Billing cycles the discount applies, when duration is `repeating`.
        max_redemptions:
          type: integer
          nullable: true
        redeemed_count:
          type: integer
          example: 0
        redeem_by:
          type: string
          format: date-time
          nullable: true
        applies_to_plan_ids:
          type: array
          nullable: true
          items:
            type: string
          description: Restrict to specific plan IDs, or `null` for all plans.
        active:
          type: boolean
        metadata:
          type: object
          nullable: true
          additionalProperties: true
        livemode:
          type: boolean
          description: '`true` when created with a live key, `false` for sandbox.'
    Error:
      type: object
      description: >-
        All error responses share a single nested envelope:


        ```json

        {
          "error": {
            "message": "Human-readable explanation.",
            "type": "authentication_error",
            "code": "api_key_invalid",
            "request_id": "req_..."
          }
        }

        ```


        The `type` field gives a broad category useful for SDK error class
        hierarchies. The `code` field is fine-grained and stable for
        programmatic branching. `request_id` is the same value as the
        `X-Request-Id` response header - quote it in support requests so we can
        find the exact request in logs.


        Some error types include extra detail objects (e.g. `error.suspension`
        on `account_suspended`, `error.pause` on `token_paused`).
      required:
        - error
      properties:
        error:
          type: object
          required:
            - message
            - type
          properties:
            message:
              type: string
              description: >-
                Human-readable error message - safe to surface to a developer,
                may include the action they need to take.
            type:
              type: string
              enum:
                - authentication_error
                - account_error
                - permission_error
                - invalid_request_error
                - idempotency_error
                - rate_limit_error
                - api_error
              description: >-
                Broad category used by SDKs to instantiate a typed exception
                (e.g. `AuthenticationError`, `InvalidRequestError`).
            code:
              type: string
              description: >-
                Specific, stable identifier for programmatic handling. Common
                values:


                - `api_key_missing` - Authorization header absent or empty
                (401).

                - `api_key_invalid` - key not recognised (401).

                - `api_key_revoked` - key was explicitly revoked (401).

                - `api_key_expired` - key passed its expiration timestamp (401).

                - `api_key_must_be_secret` - endpoint requires `sk_...`; a
                publishable `pk_...` was sent (403).

                - `account_suspended` - merchant account is suspended (403); see
                `error.suspension`.

                - `token_paused` - MCP token paused (423); see `error.pause`.

                - `forbidden` - permission check failed (403).

                - `not_found` - resource not found (404).

                - `idempotency_conflict` - concurrent request with same
                Idempotency-Key (409).

                - `rate_limited` - rate-limit window exhausted (429).
            request_id:
              type: string
              description: >-
                Same value as the `X-Request-Id` response header. Quote in
                support requests for fastest triage.
              example: req_2Je91NlWKuXkdXUJOK9gaHNW
            suspension:
              type: object
              description: Present only when `code === 'account_suspended'`.
              properties:
                suspended_at:
                  type: string
                  format: date-time
                reason:
                  type: string
                  nullable: true
            pause:
              type: object
              description: Present only when `code === 'token_paused'`.
              properties:
                paused_at:
                  type: string
                  format: date-time
                reason:
                  type: string
                  nullable: true
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        Your PayBridgeNP API key. Obtain one from the dashboard under Settings →
        API Keys. Prefix: `sk_test_` for testing, `sk_live_` for production.

````