Payment Requests
Request a payment from a recipient over iMessage. You create a payment
request, send its checkout_url to the recipient, and they pay with Apple
Pay or card. Funds settle directly to your own Stripe account — Linq
never holds the money.
How it works
- Create a payment request with an amount and currency. You get back a
checkout_urland astatusofrequested. - Send the
checkout_urlto the recipient as alinkmessage part so it arrives as a tappable card (see Sending the link below). - The recipient pays on the hosted checkout (Apple Pay App Clip on a supported iPhone, web checkout everywhere else).
- You receive a
payment.succeededwebhook and the request’sstatusbecomessucceeded. Requests you don’t collect eventuallyexpire.
Connected accounts (Stripe Standard, direct charges)
Payments run on Stripe Connect Standard accounts using direct charges: the charge is created on your connected account and you are the merchant of record. That means the money, the payout schedule, the customer relationship, and the compliance surface are all yours — Linq orchestrates the request and the checkout but is never in the funds flow.
Refunds, disputes, and chargebacks are handled by you, in your own Stripe Dashboard. Because charges settle directly to your account, Linq has no custody of the funds and cannot issue refunds or contest disputes on your behalf — and there is no refund/dispute endpoint in this API by design. Use the Stripe Dashboard (or the Stripe API on your own account) for the money lifecycle after a payment succeeds.
Getting set up
Open Agent Pay in your Linq dashboard
(https://zero.linqapp.com/organization/payments), click Connect Stripe,
and complete Stripe’s onboarding (business details + a bank account). When
your account reaches charges_enabled, request creation unlocks; until you
connect Stripe, POST /v3/payment_requests returns 403. You can keep
collecting even while Stripe finishes background verification.
Subscriptions
Set mode: subscription on POST /v3/payment_requests to start an
auto-renewing subscription instead of a one-time charge. Instead of an
amount, you pass a price_id — an active recurring Price on your
connected Stripe account (create one in your Stripe Dashboard under
Product catalog; if you sell through Stripe Payment Links today, reuse the
price your link is built from). The recipient pays the first invoice at
the same checkout, and their payment method is saved to the subscription
for automatic renewals.
The division of labor is deliberate: Linq handles the first payment,
your Stripe account handles the rest. The request reaches succeeded
when the first invoice is paid; from then on the subscription lives
entirely on your connected account. The response’s stripe object gives
you the join keys — customer_id and subscription_id — so renewals,
plan changes, dunning, and cancellation are managed with your own Stripe
Dashboard/API and your own Stripe webhooks. Your metadata is stamped on
the Customer and Subscription, so correlating in either direction is
trivial. There are no renewal webhooks from Linq by design.
Free trials
Add trial_period_days (or a fixed trial_end timestamp) to start the
subscription with a free trial. The checkout still collects the
recipient’s payment method — the pay sheet shows “$0 due today” with the
first charge date — and saves it to the subscription; Stripe bills it
automatically when the trial ends. The request reaches succeeded when
the card is collected, and the response carries trial_end. If the trial
would end without a payment method on file, the subscription cancels
rather than generating unpayable invoices. Trial lifecycle after checkout
(extending, ending early) is managed in your own Stripe account via
stripe.subscription_id.
A subscription request you cancel (or that expires unpaid) cancels the incomplete Stripe subscription — nothing lingers on your account.
Pre-created customers
By default each request stands alone: payment mode attaches no Customer,
and subscription mode creates a fresh one. If you already manage
Customers on your connected account, pass their id as customer_id
(cus_...) on create — in payment mode the charge lands on that
customer’s payment history, and in subscription mode the subscription is
created on them instead of on a new Customer. The id must reference an
existing, non-deleted customer on your connected account or the request
fails with 400. We never modify a customer you pass — no metadata is
stamped on it.
Sending the link
Deliver the checkout_url as a link message part via
POST /v3/chats/{chatId}/messages — it renders as a rich card with your
branding (title, amount, image) instead of a bare URL, which converts far
better. A link part must be the only part in the message. See
Rich Link Previews.
On a supported iPhone the link opens an Apple Pay App Clip — a native, no-install checkout sheet. Everywhere else (Android, desktop, iPhones without the App Clip yet) the same URL opens the web checkout, so the link always works. The App Clip experience for your payment links is registered automatically by Linq and refreshed whenever you update your payments branding; a newly registered experience can take up to ~24 hours to activate on Apple’s side, during which links open the web checkout.
Webhooks
Subscribe to payment lifecycle events to reconcile server-side rather than
polling: payment.succeeded, payment.canceled, and payment.expired.
Each event carries the payment request id, amount, currency, and your
metadata. See Webhooks.