Skip to main content

Checkouts

Execute purchases programmatically on any e-commerce website. Provide a product or cart URL along with customer and payment information, and SimpleCheckout handles the entire checkout process via browser automation. No need for merchant-specific API integrations or manual intervention.

See API Reference for complete endpoint documentation.

How It Works

Create a checkout with a product/cart URL and customer information, then poll for status updates. The process is asynchronous - you get an immediate response with a checkout ID.

Checkout Process

  1. Initiation: You provide a URL (product page, cart page, or checkout URL) and necessary information
  2. Validation: System checks that all required data is present (payment token, shipping info, etc.)
  3. Execution: Browser automation agent navigates the site and completes the checkout
  4. Completion: Checkout status updates to completed or failed with details

Checkout Lifecycle

  • pending - Checkout queued for execution
  • pending_cvc_verification - Paused waiting for CVC refresh (see CVC Verification)
  • completed - Purchase successfully executed (terminal state)
  • failed - Purchase could not be completed (terminal state)

Secure Payment Injection

Payment details are never sent directly to the merchant's site. Instead:

  1. You provide a credit_card_token (from Tokenizing Credit Cards)
  2. The automation agent uses placeholder card data during checkout
  3. At the moment of payment submission, our secure proxy intercepts the request
  4. The proxy replaces placeholder data with real tokenized card details
  5. The request proceeds to the payment processor

This approach ensures PCI compliance and prevents card data exposure.

Request Parameters

URL Types

The checkout URL can be:

  • Product page - Direct link to a product (e.g., https://nike.com/shoes/air-max-90)
  • Cart page - A pre-filled shopping cart
  • Checkout page - A cart ready for payment

The automation handles all three types, navigating from wherever the URL points to final purchase completion.

Customer Data

You can provide customer information in two ways:

Customer-based approach (Recommended):

  • Use customer_id to reference a customer profile
  • Optionally specify address_id and credit_card_token
  • Defaults to customer's saved address and payment method if not specified

Legacy user_data approach:

  • Pass customer data directly in the request
  • Include all required information (email, name, address, etc.)
  • Add any product-specific details (size, color, quantity)

Customer Integration Benefits

Using customer profiles provides:

  • Centralized data management: Update customer info in one place
  • Default payment methods: Customer can save tokenized cards for reuse
  • Multiple addresses: Choose specific addresses per checkout or use defaults
  • Better tracking: Checkouts show display_name (typically email) for easy identification

When to use each approach:

  • Use customer_id when you want to manage customer data centrally and reuse information across checkouts
  • Use user_data for one-off checkouts when customer management isn't needed

Credit Card Token

The credit_card_token is obtained by tokenizing a customer's card via:

  • The Playground for testing
  • The SDK for production
  • Direct VGS integration (advanced)

See Tokenizing Credit Cards for details.

Alternative: Platform-funded virtual cards are available upon request. Contact [email protected] to discuss this option.

Complete Example

Using customer_id (Recommended):

import requests
import time

api_key = "YOUR_API_KEY"

headers = {
"api-key": api_key,
"Content-Type": "application/json"
}

# Create checkout with customer reference
checkout_response = requests.post(
"https://api.simplecheckout.ai/v0/checkouts",
headers=headers,
json={
"url": "https://buy.stripe.com/test_cNi3cvg0GeLkagX1un6Ri0m",
"customer_id": "cust_abc123",
"credit_card_token": "cct_sandbox_xyz456"
# address_id is optional - will use customer's default if not provided
}
)

checkout = checkout_response.json()
checkout_id = checkout["id"]

print(f"Checkout created: {checkout_id}")
print(f"Status: {checkout['status']}")

# Poll for completion
while True:
checkout = requests.get(
f"https://api.simplecheckout.ai/v0/checkouts/{checkout_id}",
headers=headers
).json()

status = checkout["status"]
print(f"Status: {status}")

if status in ["completed", "failed"]:
break

time.sleep(30) # Check every 30 seconds

# Final result
if checkout["status"] == "completed":
print(f"✅ Purchase completed!")
print(f"Customer: {checkout['display_name']}")
print(f"Amount: ${checkout['amount_str']} {checkout['currency']}")
else:
print(f"❌ Purchase failed")
print(f"Notes: {checkout['notes']}")

Using user_data (Legacy approach for one-off checkouts):

# Create checkout with inline user data
checkout_response = requests.post(
"https://api.simplecheckout.ai/v0/checkouts",
headers=headers,
json={
"url": "https://buy.stripe.com/test_cNi3cvg0GeLkagX1un6Ri0m",
"user_data": {
"email": "[email protected]",
"first_name": "John",
"last_name": "Doe"
},
"credit_card_token": "cct_sandbox_abc123"
}
)
# ... rest of polling logic same as above

Using with Carts

You can use the Carts API to build a cart with accurate pricing, then execute the checkout:

# 1. Build cart with Carts API
cart = requests.post(
"https://api.simplecheckout.ai/v0/carts",
headers={"api-key": api_key}
).json()

# 2. Add items
requests.post(
f"https://api.simplecheckout.ai/v0/carts/{cart['id']}/lines",
headers={"api-key": api_key},
json={"product_variant_id": "pv_abc123", "quantity": 1}
)

# 3. Add address for pricing
cart = requests.patch(
f"https://api.simplecheckout.ai/v0/carts/{cart['id']}",
headers={"api-key": api_key},
json={"shipping_address": {...}}
).json()

# 4. Execute checkout with merchant URL
# (You'll need the specific merchant's checkout URL for these items)
checkout = requests.post(
"https://api.simplecheckout.ai/v0/checkouts",
headers=headers,
json={
"url": "https://merchant.com/checkout/...",
"user_data": cart["shipping_address"],
"credit_card_token": "cct_..."
}
).json()

The cart response includes line_items with a merchant_id for each item and a carts array summarizing per-merchant totals and the line_item_ids that belong to each merchant:

{
"line_items": [
{ "id": "li_1", "merchant_id": "m_123", "product_variant_id": "pv_abc", "quantity": 1, "unit_price": "49.99", "line_price": "49.99", "currency": "USD" }
],
"carts": [
{ "merchant_id": "m_123", "subtotal_price": "49.99", "shipping_price": "8.99", "tax_price": "0.00", "total_price": "58.98", "currency": "USD", "line_item_ids": ["li_1"] }
],
"subtotal_price": "49.99",
"shipping_price": "8.99",
"tax_price": "0.00",
"total_price": "58.98"
}

Group items by merchant_id when you need to pass a merchant-specific checkout URL. See the full cart response in the Carts API.

Error Handling

Common Failure Reasons

When a checkout fails, the notes field contains details:

  • "Payment declined" - Card was rejected by payment processor
  • "Item out of stock" - Product no longer available
  • "Price changed" - Item price increased between start and execution
  • "Missing information" - Required checkout fields weren't provided in user_data
  • "Invalid address" - Merchant doesn't ship to provided address
  • "Site error" - Merchant's website had technical issues

Handling CVC Verification

If a checkout status becomes pending_cvc_verification, the stored CVC has expired. See CVC Verification for handling this:

checkout = requests.get(
f"https://api.simplecheckout.ai/v0/checkouts/{checkout_id}",
headers=headers
).json()

if checkout["status"] == "pending_cvc_verification":
# Check payment readiness
ready = requests.get(
f"https://api.simplecheckout.ai/v0/payment-ready?credit_card_token={checkout['credit_card_token']}",
headers=headers
).json()

if not ready["payment_ready"]:
# User needs to verify CVC at verification_url
print(f"Please verify CVC at: {ready['verification_url']}")
# Checkout will auto-resume after verification

Best Practices

Polling Strategy

  • Initial delay: Wait at least 15 seconds before first status check
  • Poll interval: Check every 30-60 seconds (not more frequently)
  • Timeout: Consider checkout failed if pending for > 10 minutes

User Data Completeness

  • Include all fields: Even optional ones (phone, apartment number, etc.)
  • Format addresses correctly: Match expected formats (e.g., "+1234567890" for phone)
  • Test with various merchants: Requirements vary by site

Payment Tokens

  • Check payment readiness before creating checkout (see CVC Verification)
  • Handle expired CVCs gracefully by pausing and requesting refresh
  • Use sandbox tokens (cct_sandbox_...) for testing

Monitoring

  • Log checkout IDs: Essential for debugging failed purchases
  • Track failure patterns: Some merchants may have specific requirements
  • Monitor completion times: Unusual delays may indicate issues

Limitations

  • Execution time: Variable (30-90 seconds typical, up to 5 minutes possible)
  • Merchant support: Works with most sites, but complex flows may fail
  • Dynamic content: Heavy JavaScript sites may have inconsistent results
  • Rate limits: Contact support for high-volume usage guidance

Testing

For testing, use:

  • Stripe test URLs: https://buy.stripe.com/test_... (various test scenarios)
  • Sandbox card tokens: cct_sandbox_... from the playground
  • Test email: Any email address you control

Stripe test checkout links support different scenarios (with/without address required, different payment methods, etc.).

What's Next?