Products and no-code payment links
Create products and shareable payment links for the hosted checkout at /pay/:slug. Buyers pay via C2P against your tenant; VEX Pay’s cut is captured as PLATFORM_FEE on payment.completed.
Endpoints
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/products | Create a product (name, priceUsd, optional description / imageUrl / active). |
| GET | /v1/products | List products (cursor pagination; ?active=true|false). |
| GET | /v1/products/:id | Get a product and its payment links. |
| PATCH | /v1/products/:id | Update fields — send only what changes; "" clears description / imageUrl. |
| DELETE | /v1/products/:id | Delete product + its links. 409 product_has_sales if a checkout was paid. |
| POST | /v1/products/:id/links | Create a payment link. Omit slug to auto-generate from the product name. |
| GET | /v1/products/:id/links | List a product’s payment links. |
| GET | /v1/payment-links/:id | Get one payment link. |
| PATCH | /v1/payment-links/:id | Enable/disable (status), toggle allowQuantity, set maxQuantity / redirectUrl. |
| DELETE | /v1/payment-links/:id | Delete a link. 409 product_has_sales if a checkout on it was paid — disable instead. |
curl --request POST "${API_URL}/v1/products" \
--header "x-api-key: ${VEXPAY_API_KEY}" \
--header "content-type: application/json" \
--data '{ "name": "Camiseta VEXPay", "priceUsd": "20.00" }'curl --request POST "${API_URL}/v1/products/PRODUCT_ID/links" \
--header "x-api-key: ${VEXPAY_API_KEY}" \
--header "content-type: application/json" \
--data '{ "allowQuantity": true, "maxQuantity": 5 }'{
"id": "…",
"productId": "…",
"slug": "camiseta-vexpay-40753a",
"hostedCheckoutPath": "/pay/camiseta-vexpay-40753a",
"status": "active",
"allowQuantity": true,
"maxQuantity": 5,
"redirectUrl": null,
"createdAt": "…"
}