Skip to main content
Initiates a new checkout session for purchasing a product. Creates a sale record and either returns a payment checkout URL for paid products or completes the sale immediately for free products.
Unsupported product types: the following cannot be used to initiate a checkout through the API:
  • Service products
  • Coaching products
  • Products with pay-what-you-want pricing
For these, redirect customers to your Chariow storefront or use the Snap Widget embed on your website.
All sales initiated via this API endpoint will have their Channel set to “API” on your store dashboard. This helps you identify and track sales originating from your API integrations separately from other channels.
Rate limit: checkout has its own rate-limit bucket of 100 requests per minute per API key, counted separately from the rest of the Public API. A sync job that reads sales or products in bulk cannot use up the budget your buyers need to start a payment. When the limit is exceeded, the API returns 429 Too Many Requests.
Required scope: checkout.write. A key without it receives a 403 error. See Authentication.

Repeat Purchases

The ability to purchase a product multiple times depends on the product type:
For blocked product types, if a customer’s access has been revoked (e.g., after a refund), they will be able to purchase the product again. The system checks for active access grants only.

Authentication

This endpoint requires API key authentication via Bearer token:

Request Body

string
required
The product public ID or slug to purchase. The product must be published. Example: prd_abc123xyz or premium-course
string
Identifier of an active price variant of the product (max 100 characters, case-insensitive). Only applies to products with one-time pricing. An unknown or inactive variant is ignored silently and the product’s regular price is used.
string
required
Customer email address. Must be a valid email address (strict check, max 255 characters). The address is stored in lowercase. Example: customer@example.com
string
required
Customer first name (max 50 characters). Example: John
string
required
Customer last name (max 50 characters). Example: Doe
object
required
Customer phone details
One customer per email address. Emails are compared case-insensitively, so John@Example.com and john@example.com resolve to the same customer in your store. When the customer already exists, the checkout reuses that record and updates its first name, last name and phone number with the values you send.
string
Discount code to apply (max 100 characters, case-insensitive). Discount codes only apply to products with one-time pricing. Example: SAVE20
string
Affiliate tracking code used to attribute the sale to an affiliate (max 50 characters). Example: abc12xyz
string
Campaign public ID or tracking code for analytics. An unknown campaign is ignored. Example: camp_xyz789
object
Custom field values for the product (key-value pairs). Must match the product’s configured custom fields.
string
ISO 4217 code of the currency the buyer pays in. Defaults to your store currency. The code must be a currency supported by Chariow; an unsupported code returns a 422 validation error on payment_currency. When it differs from the product currency, the price is converted and a per-currency conversion markup is included in the amount charged. Example: XOF, EUR, USD
string
Custom URL to redirect customers after payment completion (max 2048 characters). When provided, customers will be redirected to this URL instead of the default Chariow post-purchase page. Must be a valid active URL. Example: https://yoursite.com/thank-you
object
Custom key-value metadata to store with the sale. Maximum 10 keys allowed, each value limited to 255 characters. This metadata is included in Pulse webhook payloads, making it useful for linking sales with external systems. Example: {"order_ref": "ORD-123", "source": "landing_page"}
string
The buyer’s IP address, IPv4 or IPv6. Example: 203.0.113.42
Why send customer_ip? This endpoint is called from your server, so the IP we see is your own infrastructure, not the buyer’s. When you forward customer_ip, we store it on the sale and resolve the buyer’s country from it, which improves the payment methods offered at checkout and the accuracy of your sales analytics. When the field is omitted, or the IP cannot be located, the buyer’s country is taken from phone.country_code instead of your server’s location, and the sale records the calling IP.
string[]
HTTPS origins allowed to embed the hosted payment page (the checkout_url) in an iframe, up to 4. Each entry must be a canonical origin: lowercase https:// scheme and host, an optional non-default port, and no path, query, fragment, credentials or trailing slash. Example: ["https://shop.example.com"]
object
Buy the product as a gift for someone else. The recipient receives access to the product instead of the buyer.

Shipping Address

The shipping object is required when the product has “Require shipping address” enabled. If shipping is not required for the product, it is ignored.
object
Shipping address of the customer

Response

object
The checkout response object containing step, purchase, and payment information

Error Responses

The checkout was refused by a business rule. The message explains why, for example: invalid phone number for the given country, product sold out, no licence available, empty bundle, discount code inactive, expired, not applicable or used up, store not allowed to receive orders, or the payment session could not be opened (the sale is then marked as failed).
Invalid or missing API key
Product not found or not published, or discount code not found
The gift recipient already owns this product
Validation errors (including an unsupported payment_currency or an unknown country code), pay-what-you-want product, unsupported product type (Service, Coaching), or a gift addressed to the buyer
Checkout rate limit exceeded