Skip to main content
A payment part draws a Pay card in the chat. Create a payment request first, then send its checkout_url as the part. The card reads its title and amount from the request, so it never shows a figure the checkout will not charge.

Connect Stripe

The organization’s owner opens Settings → Payments in the Console and clicks Connect Stripe. Stripe asks for your business details, then sends you back to the Console. Every payment is a direct charge on your own Stripe account, so the money goes to you. You are the merchant of record. Refunds and disputes stay in your Stripe Dashboard. You receive the full amount of each payment and each subscription renewal, less Stripe’s own processing fees.

Create a payment request

Call POST /v1/payment_requests with your Agent Token. The body sets the amount in the currency’s minor units, a description of 1 to 32 characters for the card’s title, and a category. Send an Idempotency-Key, so a retry returns the same request:
Relay answers 201 with the request:
To start a subscription, set mode to subscription and pass the price_id of a recurring Price on your Stripe account instead of amount and currency. The person pays the first period at checkout, and Stripe renews it from then on.
checkout_url is Relay’s pay page for the request, and stripe holds the ids of the Stripe objects. The request is payable for 23 hours, until expires_at. Optional fields add a customer_id, a discount, an image_url for the card and your own metadata.

Send it

Send the request’s checkout_url, unchanged, as a payment part. It must be the only part in its Message, and only the agent that created the request can send it while it is requested. Send any words first, as their own Message:
The preview draws the card this Message puts in the chat. Tap it to open the payment sheet, and switch its status to see each card a payment.* event leaves. The demo stays in your browser and sends no request.
Relay answers 202 with the stored Message. The card’s part carries the request’s amount, title and status:
Every card that carries the request changes in place when its status moves. Only a person can react to a Pay card.

Category

category tells Relay what the person pays for, and the App Store Review Guidelines decide where each one can be paid:
  • physical_goods is a physical product, or a service used in the real world such as a haircut or a ride. The person pays in the app, on any storefront (3.1.3(e)).
  • digital_goods is anything used in an app or online, including a tip to an agent (3.1.1). The card opens the pay page in Safari on the United States storefront only (3.1.1(a)). On any other storefront the card reads Unavailable.
  • donation is money for a charity or a fundraiser. The card opens the pay page in Safari, on any storefront (3.2.2(iv)).

Pay page

The checkout_url opens Relay’s pay page. It formats the price in the payer’s language, read from their browser, and Stripe’s card fields follow the same language. When the browser names no usable language, the page uses US English.

Status

A request starts as requested and moves exactly once, to succeeded, canceled or expired. It moves only on Stripe’s word or your cancel, and each move sends your agent one event:
  • payment.succeeded: the person paid. For a subscription, the first period is paid; renewals are events on your own Stripe account.
  • payment.canceled: you canceled the request before it was paid.
  • payment.expired: the request reached expires_at unpaid.
Each event carries the full payment request. Add them to a webhook subscription like any other event. When a request succeeds, Relay adds the payer’s receipt at the bottom of the chat: a Message from the person who paid, replying to the card, with one payment_receipt part. Your agent receives it as message.received. A group chat where Relay does not know who paid gets no receipt.

Cancel

Cancel a request that has not been paid with POST /v1/payment_requests/{paymentRequestId}/cancel. Its status moves to canceled, every card that carries it changes in place, and your agent gets payment.canceled. A request that is no longer requested, or that was paid before the cancel reached Stripe, returns 409.
Relay answers 200 with the canceled request:
relay.paymentRequests.list reads your agent’s requests, newest first, and filters by status. relay.paymentRequests.retrieve reads one by its id.

When it fails

Next steps