# Payment Requests

## Create a payment request

**post** `/v3/payment_requests`

Creates a payment request and returns a `checkout_url` the recipient
opens to pay with Apple Pay or card. Funds settle directly to your
connected Stripe account. A payment request is independent of any chat;
to associate one with a chat for your records, store the chat id in
`metadata`. Requires your connected account to be `charges_enabled`
(returns `403` otherwise).

Set `mode: subscription` with a recurring `price_id` from your connected
Stripe account to start an **auto-renewing subscription** instead of a
one-time charge — the recipient pays the first invoice at checkout and
the response's `stripe` object carries the customer and subscription ids
for the ongoing lifecycle in your own Stripe account. See the
*Subscriptions* section of the tag overview.

In either mode, pass `customer_id` to attach the request to an
**existing Customer** on your connected account instead of creating a
new one — see *Pre-created customers* in the tag overview.

### Header Parameters

- `"Idempotency-Key": optional string`

### Body Parameters

- `amount: optional number`

  Amount to charge, in the currency's minor units (e.g. cents). Must be
  at least the payment provider's minimum (50 for `usd`). Required in
  `payment` mode; must be omitted in `subscription` mode (the amount
  comes from the price).

- `currency: optional string`

  Three-letter ISO 4217 currency code. Only `usd` is currently
  supported. Required in `payment` mode; must be omitted in
  `subscription` mode (the currency comes from the price).

- `customer_id: optional string`

  Optional id of an **existing Customer** on your connected Stripe
  account (`cus_...`) to attach this request to, instead of a new
  Customer being created. In `payment` mode the charge lands on that
  customer's payment history; in `subscription` mode the subscription
  is created on them. The customer must exist (and not be deleted) on
  your connected account.

- `description: optional string`

  Optional description shown to the recipient at checkout.

- `metadata: optional map[string]`

  Optional key/value metadata (up to 49 keys) echoed back on retrieval
  and on `payment.*` webhooks, and stamped on the Stripe objects we
  create on your connected account (the PaymentIntent, and in
  subscription mode the Subscription and any Customer created for
  you — a customer you pass via `customer_id` is never modified) —
  use it to correlate a request with your own records (e.g. a chat
  id). Keys starting with `linq_` are reserved.

- `mode: optional "payment" or "subscription"`

  `payment` (default) collects a one-time charge for `amount` +
  `currency`. `subscription` starts an auto-renewing subscription from
  a recurring `price_id` on your connected Stripe account: the
  recipient pays the first invoice at checkout and Stripe renews it
  automatically from then on.

  - `"payment"`

  - `"subscription"`

- `price_id: optional string`

  Subscription mode only (required there): id of an **active recurring
  Price** on your connected Stripe account (`price_...`). If you sell
  through Stripe Payment Links today, pass the same price the link was
  built from to get the native iMessage checkout for it.

- `quantity: optional number`

  Subscription mode only — units of the price to subscribe to.

- `trial_end: optional string`

  Subscription mode only — end the free trial at a fixed timestamp
  (must be in the future) instead of a day count. Mutually exclusive
  with `trial_period_days`.

- `trial_period_days: optional number`

  Subscription mode only — start with a free trial of this many days.
  The recipient's card is still collected at checkout (Apple Pay or
  card), saved to the subscription, and first charged when the trial
  ends. Mutually exclusive with `trial_end`.

### Returns

- `PaymentRequest object { id, amount, checkout_url, 16 more }`

  - `id: string`

    Unique identifier of the payment request.

  - `amount: number`

    Amount in the currency's minor units. In `subscription` mode this is
    the recurring amount (price × quantity) the recipient pays per
    interval, starting at checkout.

  - `checkout_url: string`

    URL the recipient opens to pay:
    `https://zero.linqapp.com/pay/{slug}?session=...`, where `{slug}`
    is your partner checkout slug.

  - `created_at: string`

  - `currency: string`

  - `mode: "payment" or "subscription"`

    Whether this request collects a one-time charge or starts a subscription.

    - `"payment"`

    - `"subscription"`

  - `object: string`

  - `status: "requested" or "succeeded" or "canceled" or "expired"`

    Lifecycle status of the payment request.

    - `"requested"`

    - `"succeeded"`

    - `"canceled"`

    - `"expired"`

  - `description: optional string`

  - `expires_at: optional string`

    When an unpaid request auto-expires.

  - `interval: optional "day" or "week" or "month" or "year"`

    Subscription mode — how often the subscription renews.

    - `"day"`

    - `"week"`

    - `"month"`

    - `"year"`

  - `interval_count: optional number`

    Subscription mode — intervals per renewal (e.g. `3` + `month` = quarterly).

  - `metadata: optional map[string]`

  - `paid_at: optional string`

    When the request was paid. Absent until it succeeds.

  - `price_id: optional string`

    Subscription mode — the recurring price this request subscribes to.

  - `quantity: optional number`

    Subscription mode — units of the price subscribed to.

  - `stripe: optional object { customer_id, payment_intent_id, subscription_id }`

    Ids of the Stripe objects created **on your connected account** —
    your join keys into your own Stripe Dashboard, webhooks, and API.
    After a subscription's first payment succeeds, its ongoing lifecycle
    (renewals, plan changes, cancellation) is managed in your Stripe
    account using `subscription_id`.

    - `customer_id: optional string`

      The Customer this request is attached to (`cus_...`). Always set
      in subscription mode (created for you unless you passed
      `customer_id`); set in payment mode only when you passed one.

    - `payment_intent_id: optional string`

      The PaymentIntent collected at checkout (`pi_...`).

    - `subscription_id: optional string`

      Subscription mode — the Subscription (`sub_...`).

  - `trial_end: optional string`

    Subscription mode — when the free trial ends and the first charge
    happens. Present only on trial requests; `paid_at`/`succeeded` mean
    the payment method was collected (no funds move until this time).

  - `updated_at: optional string`

### Example

```http
curl https://api.linqapp.com/api/partner/v3/payment_requests \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $LINQ_API_V3_API_KEY" \
    -d '{
          "amount": 497,
          "currency": "usd",
          "customer_id": "cus_QAbCdEfGhIjKlMn",
          "description": "Coffee with Ava",
          "price_id": "price_1QAbCdEfGhIjKlMn",
          "trial_period_days": 14
        }'
```

#### Response

```json
{
  "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
  "amount": 497,
  "checkout_url": "https://zero.linqapp.com/pay/tomo?session=tok_abc123",
  "created_at": "2019-12-27T18:11:19.117Z",
  "currency": "usd",
  "mode": "payment",
  "object": "payment_request",
  "status": "requested",
  "description": "description",
  "expires_at": "2019-12-27T18:11:19.117Z",
  "interval": "day",
  "interval_count": 0,
  "metadata": {
    "foo": "string"
  },
  "paid_at": "2019-12-27T18:11:19.117Z",
  "price_id": "price_id",
  "quantity": 0,
  "stripe": {
    "customer_id": "cus_QAbCdEfGhIjKlMn",
    "payment_intent_id": "pi_3QAbCdEfGhIjKlMn",
    "subscription_id": "sub_1QAbCdEfGhIjKlMn"
  },
  "trial_end": "2019-12-27T18:11:19.117Z",
  "updated_at": "2019-12-27T18:11:19.117Z"
}
```

## Get a payment request

**get** `/v3/payment_requests/{paymentRequestId}`

Returns a payment request's status and details.

### Path Parameters

- `paymentRequestId: string`

### Returns

- `PaymentRequest object { id, amount, checkout_url, 16 more }`

  - `id: string`

    Unique identifier of the payment request.

  - `amount: number`

    Amount in the currency's minor units. In `subscription` mode this is
    the recurring amount (price × quantity) the recipient pays per
    interval, starting at checkout.

  - `checkout_url: string`

    URL the recipient opens to pay:
    `https://zero.linqapp.com/pay/{slug}?session=...`, where `{slug}`
    is your partner checkout slug.

  - `created_at: string`

  - `currency: string`

  - `mode: "payment" or "subscription"`

    Whether this request collects a one-time charge or starts a subscription.

    - `"payment"`

    - `"subscription"`

  - `object: string`

  - `status: "requested" or "succeeded" or "canceled" or "expired"`

    Lifecycle status of the payment request.

    - `"requested"`

    - `"succeeded"`

    - `"canceled"`

    - `"expired"`

  - `description: optional string`

  - `expires_at: optional string`

    When an unpaid request auto-expires.

  - `interval: optional "day" or "week" or "month" or "year"`

    Subscription mode — how often the subscription renews.

    - `"day"`

    - `"week"`

    - `"month"`

    - `"year"`

  - `interval_count: optional number`

    Subscription mode — intervals per renewal (e.g. `3` + `month` = quarterly).

  - `metadata: optional map[string]`

  - `paid_at: optional string`

    When the request was paid. Absent until it succeeds.

  - `price_id: optional string`

    Subscription mode — the recurring price this request subscribes to.

  - `quantity: optional number`

    Subscription mode — units of the price subscribed to.

  - `stripe: optional object { customer_id, payment_intent_id, subscription_id }`

    Ids of the Stripe objects created **on your connected account** —
    your join keys into your own Stripe Dashboard, webhooks, and API.
    After a subscription's first payment succeeds, its ongoing lifecycle
    (renewals, plan changes, cancellation) is managed in your Stripe
    account using `subscription_id`.

    - `customer_id: optional string`

      The Customer this request is attached to (`cus_...`). Always set
      in subscription mode (created for you unless you passed
      `customer_id`); set in payment mode only when you passed one.

    - `payment_intent_id: optional string`

      The PaymentIntent collected at checkout (`pi_...`).

    - `subscription_id: optional string`

      Subscription mode — the Subscription (`sub_...`).

  - `trial_end: optional string`

    Subscription mode — when the free trial ends and the first charge
    happens. Present only on trial requests; `paid_at`/`succeeded` mean
    the payment method was collected (no funds move until this time).

  - `updated_at: optional string`

### Example

```http
curl https://api.linqapp.com/api/partner/v3/payment_requests/$PAYMENT_REQUEST_ID \
    -H "Authorization: Bearer $LINQ_API_V3_API_KEY"
```

#### Response

```json
{
  "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
  "amount": 497,
  "checkout_url": "https://zero.linqapp.com/pay/tomo?session=tok_abc123",
  "created_at": "2019-12-27T18:11:19.117Z",
  "currency": "usd",
  "mode": "payment",
  "object": "payment_request",
  "status": "requested",
  "description": "description",
  "expires_at": "2019-12-27T18:11:19.117Z",
  "interval": "day",
  "interval_count": 0,
  "metadata": {
    "foo": "string"
  },
  "paid_at": "2019-12-27T18:11:19.117Z",
  "price_id": "price_id",
  "quantity": 0,
  "stripe": {
    "customer_id": "cus_QAbCdEfGhIjKlMn",
    "payment_intent_id": "pi_3QAbCdEfGhIjKlMn",
    "subscription_id": "sub_1QAbCdEfGhIjKlMn"
  },
  "trial_end": "2019-12-27T18:11:19.117Z",
  "updated_at": "2019-12-27T18:11:19.117Z"
}
```

## List payment requests

**get** `/v3/payment_requests`

Lists your payment requests, newest first, for reconciliation. Paginate
with `limit` + `offset`; `has_more` indicates whether another page exists.

### Query Parameters

- `limit: optional number`

  Max results to return (default 20, max 100).

- `offset: optional number`

  Number of results to skip.

- `status: optional "requested" or "succeeded" or "canceled" or "expired"`

  Filter by lifecycle status.

  - `"requested"`

  - `"succeeded"`

  - `"canceled"`

  - `"expired"`

### Returns

- `data: array of PaymentRequest`

  - `id: string`

    Unique identifier of the payment request.

  - `amount: number`

    Amount in the currency's minor units. In `subscription` mode this is
    the recurring amount (price × quantity) the recipient pays per
    interval, starting at checkout.

  - `checkout_url: string`

    URL the recipient opens to pay:
    `https://zero.linqapp.com/pay/{slug}?session=...`, where `{slug}`
    is your partner checkout slug.

  - `created_at: string`

  - `currency: string`

  - `mode: "payment" or "subscription"`

    Whether this request collects a one-time charge or starts a subscription.

    - `"payment"`

    - `"subscription"`

  - `object: string`

  - `status: "requested" or "succeeded" or "canceled" or "expired"`

    Lifecycle status of the payment request.

    - `"requested"`

    - `"succeeded"`

    - `"canceled"`

    - `"expired"`

  - `description: optional string`

  - `expires_at: optional string`

    When an unpaid request auto-expires.

  - `interval: optional "day" or "week" or "month" or "year"`

    Subscription mode — how often the subscription renews.

    - `"day"`

    - `"week"`

    - `"month"`

    - `"year"`

  - `interval_count: optional number`

    Subscription mode — intervals per renewal (e.g. `3` + `month` = quarterly).

  - `metadata: optional map[string]`

  - `paid_at: optional string`

    When the request was paid. Absent until it succeeds.

  - `price_id: optional string`

    Subscription mode — the recurring price this request subscribes to.

  - `quantity: optional number`

    Subscription mode — units of the price subscribed to.

  - `stripe: optional object { customer_id, payment_intent_id, subscription_id }`

    Ids of the Stripe objects created **on your connected account** —
    your join keys into your own Stripe Dashboard, webhooks, and API.
    After a subscription's first payment succeeds, its ongoing lifecycle
    (renewals, plan changes, cancellation) is managed in your Stripe
    account using `subscription_id`.

    - `customer_id: optional string`

      The Customer this request is attached to (`cus_...`). Always set
      in subscription mode (created for you unless you passed
      `customer_id`); set in payment mode only when you passed one.

    - `payment_intent_id: optional string`

      The PaymentIntent collected at checkout (`pi_...`).

    - `subscription_id: optional string`

      Subscription mode — the Subscription (`sub_...`).

  - `trial_end: optional string`

    Subscription mode — when the free trial ends and the first charge
    happens. Present only on trial requests; `paid_at`/`succeeded` mean
    the payment method was collected (no funds move until this time).

  - `updated_at: optional string`

- `has_more: boolean`

  Whether more results exist beyond this page.

- `object: "list"`

  - `"list"`

### Example

```http
curl https://api.linqapp.com/api/partner/v3/payment_requests \
    -H "Authorization: Bearer $LINQ_API_V3_API_KEY"
```

#### Response

```json
{
  "data": [
    {
      "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
      "amount": 497,
      "checkout_url": "https://zero.linqapp.com/pay/tomo?session=tok_abc123",
      "created_at": "2019-12-27T18:11:19.117Z",
      "currency": "usd",
      "mode": "payment",
      "object": "payment_request",
      "status": "requested",
      "description": "description",
      "expires_at": "2019-12-27T18:11:19.117Z",
      "interval": "day",
      "interval_count": 0,
      "metadata": {
        "foo": "string"
      },
      "paid_at": "2019-12-27T18:11:19.117Z",
      "price_id": "price_id",
      "quantity": 0,
      "stripe": {
        "customer_id": "cus_QAbCdEfGhIjKlMn",
        "payment_intent_id": "pi_3QAbCdEfGhIjKlMn",
        "subscription_id": "sub_1QAbCdEfGhIjKlMn"
      },
      "trial_end": "2019-12-27T18:11:19.117Z",
      "updated_at": "2019-12-27T18:11:19.117Z"
    }
  ],
  "has_more": true,
  "object": "list"
}
```

## Cancel a payment request

**post** `/v3/payment_requests/{paymentRequestId}/cancel`

Cancels an unpaid payment request: the underlying payment intent is
canceled and the request moves to `canceled`. A request that is already
paid, canceled, or expired returns 409.

### Path Parameters

- `paymentRequestId: string`

### Returns

- `PaymentRequest object { id, amount, checkout_url, 16 more }`

  - `id: string`

    Unique identifier of the payment request.

  - `amount: number`

    Amount in the currency's minor units. In `subscription` mode this is
    the recurring amount (price × quantity) the recipient pays per
    interval, starting at checkout.

  - `checkout_url: string`

    URL the recipient opens to pay:
    `https://zero.linqapp.com/pay/{slug}?session=...`, where `{slug}`
    is your partner checkout slug.

  - `created_at: string`

  - `currency: string`

  - `mode: "payment" or "subscription"`

    Whether this request collects a one-time charge or starts a subscription.

    - `"payment"`

    - `"subscription"`

  - `object: string`

  - `status: "requested" or "succeeded" or "canceled" or "expired"`

    Lifecycle status of the payment request.

    - `"requested"`

    - `"succeeded"`

    - `"canceled"`

    - `"expired"`

  - `description: optional string`

  - `expires_at: optional string`

    When an unpaid request auto-expires.

  - `interval: optional "day" or "week" or "month" or "year"`

    Subscription mode — how often the subscription renews.

    - `"day"`

    - `"week"`

    - `"month"`

    - `"year"`

  - `interval_count: optional number`

    Subscription mode — intervals per renewal (e.g. `3` + `month` = quarterly).

  - `metadata: optional map[string]`

  - `paid_at: optional string`

    When the request was paid. Absent until it succeeds.

  - `price_id: optional string`

    Subscription mode — the recurring price this request subscribes to.

  - `quantity: optional number`

    Subscription mode — units of the price subscribed to.

  - `stripe: optional object { customer_id, payment_intent_id, subscription_id }`

    Ids of the Stripe objects created **on your connected account** —
    your join keys into your own Stripe Dashboard, webhooks, and API.
    After a subscription's first payment succeeds, its ongoing lifecycle
    (renewals, plan changes, cancellation) is managed in your Stripe
    account using `subscription_id`.

    - `customer_id: optional string`

      The Customer this request is attached to (`cus_...`). Always set
      in subscription mode (created for you unless you passed
      `customer_id`); set in payment mode only when you passed one.

    - `payment_intent_id: optional string`

      The PaymentIntent collected at checkout (`pi_...`).

    - `subscription_id: optional string`

      Subscription mode — the Subscription (`sub_...`).

  - `trial_end: optional string`

    Subscription mode — when the free trial ends and the first charge
    happens. Present only on trial requests; `paid_at`/`succeeded` mean
    the payment method was collected (no funds move until this time).

  - `updated_at: optional string`

### Example

```http
curl https://api.linqapp.com/api/partner/v3/payment_requests/$PAYMENT_REQUEST_ID/cancel \
    -X POST \
    -H "Authorization: Bearer $LINQ_API_V3_API_KEY"
```

#### Response

```json
{
  "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
  "amount": 497,
  "checkout_url": "https://zero.linqapp.com/pay/tomo?session=tok_abc123",
  "created_at": "2019-12-27T18:11:19.117Z",
  "currency": "usd",
  "mode": "payment",
  "object": "payment_request",
  "status": "requested",
  "description": "description",
  "expires_at": "2019-12-27T18:11:19.117Z",
  "interval": "day",
  "interval_count": 0,
  "metadata": {
    "foo": "string"
  },
  "paid_at": "2019-12-27T18:11:19.117Z",
  "price_id": "price_id",
  "quantity": 0,
  "stripe": {
    "customer_id": "cus_QAbCdEfGhIjKlMn",
    "payment_intent_id": "pi_3QAbCdEfGhIjKlMn",
    "subscription_id": "sub_1QAbCdEfGhIjKlMn"
  },
  "trial_end": "2019-12-27T18:11:19.117Z",
  "updated_at": "2019-12-27T18:11:19.117Z"
}
```

## Domain Types

### Payment Request

- `PaymentRequest object { id, amount, checkout_url, 16 more }`

  - `id: string`

    Unique identifier of the payment request.

  - `amount: number`

    Amount in the currency's minor units. In `subscription` mode this is
    the recurring amount (price × quantity) the recipient pays per
    interval, starting at checkout.

  - `checkout_url: string`

    URL the recipient opens to pay:
    `https://zero.linqapp.com/pay/{slug}?session=...`, where `{slug}`
    is your partner checkout slug.

  - `created_at: string`

  - `currency: string`

  - `mode: "payment" or "subscription"`

    Whether this request collects a one-time charge or starts a subscription.

    - `"payment"`

    - `"subscription"`

  - `object: string`

  - `status: "requested" or "succeeded" or "canceled" or "expired"`

    Lifecycle status of the payment request.

    - `"requested"`

    - `"succeeded"`

    - `"canceled"`

    - `"expired"`

  - `description: optional string`

  - `expires_at: optional string`

    When an unpaid request auto-expires.

  - `interval: optional "day" or "week" or "month" or "year"`

    Subscription mode — how often the subscription renews.

    - `"day"`

    - `"week"`

    - `"month"`

    - `"year"`

  - `interval_count: optional number`

    Subscription mode — intervals per renewal (e.g. `3` + `month` = quarterly).

  - `metadata: optional map[string]`

  - `paid_at: optional string`

    When the request was paid. Absent until it succeeds.

  - `price_id: optional string`

    Subscription mode — the recurring price this request subscribes to.

  - `quantity: optional number`

    Subscription mode — units of the price subscribed to.

  - `stripe: optional object { customer_id, payment_intent_id, subscription_id }`

    Ids of the Stripe objects created **on your connected account** —
    your join keys into your own Stripe Dashboard, webhooks, and API.
    After a subscription's first payment succeeds, its ongoing lifecycle
    (renewals, plan changes, cancellation) is managed in your Stripe
    account using `subscription_id`.

    - `customer_id: optional string`

      The Customer this request is attached to (`cus_...`). Always set
      in subscription mode (created for you unless you passed
      `customer_id`); set in payment mode only when you passed one.

    - `payment_intent_id: optional string`

      The PaymentIntent collected at checkout (`pi_...`).

    - `subscription_id: optional string`

      Subscription mode — the Subscription (`sub_...`).

  - `trial_end: optional string`

    Subscription mode — when the free trial ends and the first charge
    happens. Present only on trial requests; `paid_at`/`succeeded` mean
    the payment method was collected (no funds move until this time).

  - `updated_at: optional string`

### Payment Request List Response

- `PaymentRequestListResponse object { data, has_more, object }`

  - `data: array of PaymentRequest`

    - `id: string`

      Unique identifier of the payment request.

    - `amount: number`

      Amount in the currency's minor units. In `subscription` mode this is
      the recurring amount (price × quantity) the recipient pays per
      interval, starting at checkout.

    - `checkout_url: string`

      URL the recipient opens to pay:
      `https://zero.linqapp.com/pay/{slug}?session=...`, where `{slug}`
      is your partner checkout slug.

    - `created_at: string`

    - `currency: string`

    - `mode: "payment" or "subscription"`

      Whether this request collects a one-time charge or starts a subscription.

      - `"payment"`

      - `"subscription"`

    - `object: string`

    - `status: "requested" or "succeeded" or "canceled" or "expired"`

      Lifecycle status of the payment request.

      - `"requested"`

      - `"succeeded"`

      - `"canceled"`

      - `"expired"`

    - `description: optional string`

    - `expires_at: optional string`

      When an unpaid request auto-expires.

    - `interval: optional "day" or "week" or "month" or "year"`

      Subscription mode — how often the subscription renews.

      - `"day"`

      - `"week"`

      - `"month"`

      - `"year"`

    - `interval_count: optional number`

      Subscription mode — intervals per renewal (e.g. `3` + `month` = quarterly).

    - `metadata: optional map[string]`

    - `paid_at: optional string`

      When the request was paid. Absent until it succeeds.

    - `price_id: optional string`

      Subscription mode — the recurring price this request subscribes to.

    - `quantity: optional number`

      Subscription mode — units of the price subscribed to.

    - `stripe: optional object { customer_id, payment_intent_id, subscription_id }`

      Ids of the Stripe objects created **on your connected account** —
      your join keys into your own Stripe Dashboard, webhooks, and API.
      After a subscription's first payment succeeds, its ongoing lifecycle
      (renewals, plan changes, cancellation) is managed in your Stripe
      account using `subscription_id`.

      - `customer_id: optional string`

        The Customer this request is attached to (`cus_...`). Always set
        in subscription mode (created for you unless you passed
        `customer_id`); set in payment mode only when you passed one.

      - `payment_intent_id: optional string`

        The PaymentIntent collected at checkout (`pi_...`).

      - `subscription_id: optional string`

        Subscription mode — the Subscription (`sub_...`).

    - `trial_end: optional string`

      Subscription mode — when the free trial ends and the first charge
      happens. Present only on trial requests; `paid_at`/`succeeded` mean
      the payment method was collected (no funds move until this time).

    - `updated_at: optional string`

  - `has_more: boolean`

    Whether more results exist beyond this page.

  - `object: "list"`

    - `"list"`
