Subscription troubleshooting
The list below covers patterns that are commonly attempted but do not work for activating the first payment of a subscription on a new (inactive) payment instrument. If your subscription appears stuck in pending or the customer's payment is not being collected, check this list first.
For the supported flow, see Create a subscription.
What does not work
| What was attempted | Result |
|---|---|
POST /transactions with the subscription's invoiceId to pay it directly | The API accepts the request (201), but the invoiceId is ignored — the invoice stays unpaid and the subscription stays in pending. |
GET /customer-invoices/{id} followed by POST /transactions to pay the invoice | A transaction is created, but the subscription is not activated by it. The subscription stays in pending. |
POST /customer-invoices/{id}/pay | Returns 404 — this endpoint does not exist. |
| Waiting for PaymentsAI to auto-charge the new instrument | Never happens. PaymentsAI does not auto-charge inactive payment instruments. |
Frontend checks only status === 'waiting' to decide whether to redirect | Subscriptions return status: "pending", not "waiting". Without pending in the accepted-status set, the redirect to the hosted payment form is skipped. |
What does work
The only supported path for the first payment of a subscription on a new instrument is the hosted payment form:
- Create the subscription. The response returns
status: "pending"andrecentInvoicePaymentFormUrl. - Your backend surfaces
recentInvoicePaymentFormUrlto the frontend. - The frontend treats
pendingas a redirect status and sends the customer to the hosted form. - The customer completes the payment on the hosted form. PaymentsAI handles 3DS internally, activates the payment instrument, and redirects the customer back to your
redirectUrl.
See Hosted payment form for what the form does, and Payment instrument lifecycle for why the inactive instrument needs the hosted form to activate.
Common follow-up checks
- Frontend redirect status set: does the function that extracts the redirect URL accept
pendingalongsideoffsite,processing, andwaiting? Many existing 3DS-only implementations only handle the latter three. - Backend response propagation: does the backend pass
recentInvoicePaymentFormUrlto the frontend (commonly as a top-levelredirectUrlfield added to the response)? Idempotency-Key(if used): is it deterministic per(customerId, planId), not a fresh UUID? A fresh UUID on every retry creates a new subscription each time.isTrialOnlypresent: if missing, the API returns 400 before creating anything — the subscription never appears.