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

# Generate payment links for no-code payments

> Create shareable Dubu Pay-hosted payment links — no frontend code required. Collect one-time payments or attach links to existing invoices.

A checkout link is a shareable URL that opens a Dubu Pay-hosted payment page. You create the link once through the API, share it with your customer by any channel (email, SMS, chat), and Dubu Pay handles the entire payment experience — bank transfer instructions, status updates, and receipts. No custom frontend required.

## When to use checkout links vs virtual bank accounts

|                  | Checkout links                           | Virtual bank accounts                    |
| ---------------- | ---------------------------------------- | ---------------------------------------- |
| **Setup**        | No frontend code                         | Requires UI to display account details   |
| **Best for**     | One-off charges, invoices, product sales | Wallets, recurring top-ups, custom flows |
| **Payment page** | Hosted by Dubu Pay                       | You build it                             |
| **Branding**     | Dubu Pay branding                        | Fully custom                             |
| **Reuse**        | One link, many payers (one-time type)    | One account per payer / session          |

Use checkout links when you want to start collecting payments without building any UI. Use virtual bank accounts when you need a fully custom payment flow embedded in your own product.

## Create a checkout link

### Simple one-time payment link

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.dubupay.com/api/v1/checkout-links \
    -H "X-Api-Key: dubu_sk_live_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "title": "Logo Design Package",
      "description": "Professional logo design with 3 revision rounds.",
      "type": "one_time",
      "amount": 80000,
      "currency": "NGN",
      "redirect_url": "https://yoursite.com/payment/thank-you",
      "success_message": "Thank you! Your order is confirmed."
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api.dubupay.com/api/v1/checkout-links",
    {
      method: "POST",
      headers: {
        "X-Api-Key": "dubu_sk_live_your_api_key",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        title: "Logo Design Package",
        description: "Professional logo design with 3 revision rounds.",
        type: "one_time",
        amount: 80000,
        currency: "NGN",
        redirect_url: "https://yoursite.com/payment/thank-you",
        success_message: "Thank you! Your order is confirmed.",
      }),
    }
  );
  const { data: link } = await response.json();
  ```
</CodeGroup>

**Response:**

```json theme={null}
{
  "success": true,
  "data": {
    "id": "clnk_01hx9cd2qr3st4uv5wx6no",
    "title": "Logo Design Package",
    "description": "Professional logo design with 3 revision rounds.",
    "type": "one_time",
    "status": "active",
    "url": "https://pay.dubupay.com/c/logo-design-package",
    "amount": 80000,
    "currency": "NGN",
    "redirect_url": "https://yoursite.com/payment/thank-you",
    "success_message": "Thank you! Your order is confirmed.",
    "created_at": "2024-11-01T12:00:00.000Z"
  }
}
```

The `url` field is the link you share with your customer.

### Checkout link for an existing invoice

Link a checkout link to an invoice you've already created. Dubu Pay will show the invoice line items on the payment page and mark the invoice as `paid` when the payment clears.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.dubupay.com/api/v1/checkout-links \
    -H "X-Api-Key: dubu_sk_live_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "title": "Invoice INV-0001",
      "type": "invoice",
      "invoice_id": "inv_01hx9ab2qr3st4uv5wx6kl",
      "currency": "NGN"
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api.dubupay.com/api/v1/checkout-links",
    {
      method: "POST",
      headers: {
        "X-Api-Key": "dubu_sk_live_your_api_key",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        title: "Invoice INV-0001",
        type: "invoice",
        invoice_id: "inv_01hx9ab2qr3st4uv5wx6kl",
        currency: "NGN",
      }),
    }
  );
  const { data: link } = await response.json();
  ```
</CodeGroup>

### Checkout link with inline line items

Create a checkout link and define the line items inline without first creating a standalone invoice:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.dubupay.com/api/v1/checkout-links \
    -H "X-Api-Key: dubu_sk_live_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "title": "Photography Session",
      "type": "invoice",
      "customer_name": "Chisom Eze",
      "customer_email": "chisom@example.com",
      "currency": "NGN",
      "line_items": [
        {
          "description": "2-hour photo session",
          "quantity": 1,
          "unit_price": 120000
        },
        {
          "description": "10 edited photos (digital delivery)",
          "quantity": 1,
          "unit_price": 30000
        }
      ]
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api.dubupay.com/api/v1/checkout-links",
    {
      method: "POST",
      headers: {
        "X-Api-Key": "dubu_sk_live_your_api_key",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        title: "Photography Session",
        type: "invoice",
        customer_name: "Chisom Eze",
        customer_email: "chisom@example.com",
        currency: "NGN",
        line_items: [
          {
            description: "2-hour photo session",
            quantity: 1,
            unit_price: 120000,
          },
          {
            description: "10 edited photos (digital delivery)",
            quantity: 1,
            unit_price: 30000,
          },
        ],
      }),
    }
  );
  const { data: link } = await response.json();
  ```
</CodeGroup>

**All request fields:**

| Field             | Type   | Required | Description                                                                 |
| ----------------- | ------ | -------- | --------------------------------------------------------------------------- |
| `title`           | string | Yes      | Displayed on the payment page (max 255 chars)                               |
| `description`     | string | No       | Additional context for the payer (max 2000 chars)                           |
| `type`            | string | No       | `one_time` (default) or `invoice`                                           |
| `slug`            | string | No       | Custom URL slug, e.g. `logo-design`. Lowercase alphanumeric and dashes only |
| `currency`        | string | No       | `NGN` or `USD`                                                              |
| `amount`          | number | No       | Required for `one_time` links without line items                            |
| `invoice_id`      | string | No       | Link to an existing invoice UUID                                            |
| `customer_name`   | string | No       | Pre-fill customer name on the payment page                                  |
| `customer_email`  | string | No       | Pre-fill customer email                                                     |
| `line_items`      | array  | No       | Define items inline when `type` is `invoice`                                |
| `redirect_url`    | string | No       | URL to redirect the payer after successful payment                          |
| `success_message` | string | No       | Message displayed after payment (max 500 chars)                             |

## Share the link with customers

Once created, the `url` in the response is ready to share. You can:

* Embed it as a button or hyperlink in your own emails
* Copy it into an SMS or WhatsApp message
* Display it as a QR code in a physical location
* Add it to a PDF invoice as a "Pay now" link

<Tip>
  Use a custom `slug` to create memorable links like `https://pay.dubupay.com/c/your-brand-name` instead of the auto-generated URL.
</Tip>

## Update a checkout link

You can update the title, description, redirect URL, success message, or status (`active` / `inactive`) of any link:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH \
    https://api.dubupay.com/api/v1/checkout-links/clnk_01hx9cd2qr3st4uv5wx6no \
    -H "X-Api-Key: dubu_sk_live_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "status": "inactive",
      "success_message": "Payment received. We will be in touch within 24 hours."
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api.dubupay.com/api/v1/checkout-links/clnk_01hx9cd2qr3st4uv5wx6no",
    {
      method: "PATCH",
      headers: {
        "X-Api-Key": "dubu_sk_live_your_api_key",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        status: "inactive",
        success_message:
          "Payment received. We will be in touch within 24 hours.",
      }),
    }
  );
  const { data: updated } = await response.json();
  ```
</CodeGroup>

Setting `status` to `inactive` disables the link so new visitors see an error page instead of the payment form. Existing payments in progress are not affected.

## List checkout links

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://api.dubupay.com/api/v1/checkout-links?status=active&limit=20" \
    -H "X-Api-Key: dubu_sk_live_your_api_key"
  ```

  ```javascript Node.js theme={null}
  const params = new URLSearchParams({ status: "active", limit: "20" });
  const response = await fetch(
    `https://api.dubupay.com/api/v1/checkout-links?${params}`,
    {
      headers: { "X-Api-Key": "dubu_sk_live_your_api_key" },
    }
  );
  const { data } = await response.json();
  ```
</CodeGroup>

Filter by `status` (`active` or `inactive`). Supports `page` and `limit` (max 100).

## Delete a checkout link

```bash cURL theme={null}
curl -X DELETE \
  https://api.dubupay.com/api/v1/checkout-links/clnk_01hx9cd2qr3st4uv5wx6no \
  -H "X-Api-Key: dubu_sk_live_your_api_key"
```

<Warning>
  Deleting a checkout link is permanent. Any customer who visits the URL after deletion will see an error. Prefer setting `status: "inactive"` if you may want to reactivate the link later.
</Warning>

## Receive payment notifications

When a customer pays through a checkout link, Dubu Pay fires a `checkout.payment.completed` webhook event to all of your registered endpoints. Subscribe to this event to fulfil orders automatically. See the [Webhooks guide](/guides/webhooks) for setup details.
