> ## Documentation Index
> Fetch the complete documentation index at: https://docs-test.rye.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart: Send an Order to Any Merchant

> Learn how to integrate the Rye API, from setting up your account to submitting your first order. The example uses Shopify, but the same process works with Amazon, non-Shopify stores, and other merchants.

export const OpenWithLLM = ({prompt, tools}) => {
  const handleClick = (tool, e) => {
    const btn = e.currentTarget;
    const labelSpan = btn.querySelector('[data-label]');
    const copiedLabel = btn.getAttribute('data-copied');
    if (tool === 'claude') {
      window.open(`https://claude.ai/new?q=${encodeURIComponent(prompt)}`, '_blank');
      return;
    }
    if (tool === 'lovable') {
      window.open(`https://lovable.dev/?autosubmit=true#prompt=${encodeURIComponent(prompt)}`, '_blank');
      return;
    }
    navigator.clipboard.writeText(prompt);
    if (labelSpan && copiedLabel) {
      const original = labelSpan.textContent;
      labelSpan.textContent = copiedLabel;
      setTimeout(() => {
        labelSpan.textContent = original;
      }, 2500);
    }
    if (tool === 'chatgpt') {
      window.open('https://chatgpt.com/', '_blank');
    }
  };
  const show = tool => !tools || tools.includes(tool);
  const buttonBase = "inline-flex items-center gap-2 px-4 py-2.5 rounded-lg text-sm font-medium transition-all duration-200 border cursor-pointer";
  return <div className="my-6 rounded-xl border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/50 p-5">
      <div className="flex items-center gap-2 mb-3">
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="text-gray-500 dark:text-gray-400">
          <path d="M12 2L2 7l10 5 10-5-10-5z" />
          <path d="M2 17l10 5 10-5" />
          <path d="M2 12l10 5 10-5" />
        </svg>
        <span className="text-sm font-semibold text-gray-700 dark:text-gray-200">Build this with AI</span>
      </div>
      <p className="text-xs text-gray-500 dark:text-gray-400 mb-4">
        Open a pre-built prompt in your preferred AI tool to generate a complete working integration.
      </p>
      <div className="flex flex-wrap gap-2">
        {show('claude') && <button onClick={e => handleClick('claude', e)} data-copied="Opening..." className={`${buttonBase}`}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
              <path d="M4.709 15.955l4.72-2.756.08-.046 2.698-1.575c.092-.054.153-.063.2-.063.046 0 .107.01.199.063l2.698 1.575 4.8 2.802c.026.014.04.022.064.037l-7.552 4.41a.46.46 0 01-.232.063.46.46 0 01-.232-.063L4.709 15.955zm7.897-12.42l7.585 4.428a.471.471 0 01.233.408v8.747c0 .03-.003.057-.01.094l-4.812-2.81-2.698-1.574a.384.384 0 01-.199-.327V3.535zm-1.212 0v8.966a.384.384 0 01-.2.327L8.498 14.4l-4.812 2.81a.519.519 0 01-.01-.095V8.37c0-.17.09-.326.233-.408l7.485-4.428z" />
            </svg>
            <span data-label>Open in Claude</span>
          </button>}

        {show('lovable') && <button onClick={e => handleClick('lovable', e)} data-copied="Opening..." className={`${buttonBase}`}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
              <path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" />
            </svg>
            <span data-label>Open in Lovable</span>
          </button>}

        {show('chatgpt') && <button onClick={e => handleClick('chatgpt', e)} data-copied="Copied! Paste in ChatGPT" className={`${buttonBase}`}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
              <path d="M22.282 9.821a5.985 5.985 0 00-.516-4.91 6.046 6.046 0 00-6.51-2.9A6.065 6.065 0 0011.708.414a6.116 6.116 0 00-5.89 4.412 6.005 6.005 0 00-4.014 2.91 6.048 6.048 0 00.749 7.084 5.98 5.98 0 00.516 4.911 6.051 6.051 0 006.511 2.9 6.056 6.056 0 004.548 1.956 6.116 6.116 0 005.889-4.411 6.006 6.006 0 004.014-2.912 6.043 6.043 0 00-.749-7.084zM13.109 21.95a4.582 4.582 0 01-2.94-1.063c.037-.02.102-.056.144-.081l4.884-2.822a.794.794 0 00.4-.688v-6.892l2.064 1.192a.073.073 0 01.04.056v5.707a4.601 4.601 0 01-4.592 4.592zM3.6 17.938a4.556 4.556 0 01-.546-3.072c.036.021.099.06.144.084l4.884 2.822a.796.796 0 00.79 0l5.964-3.444v2.384a.074.074 0 01-.03.063L9.88 19.615a4.6 4.6 0 01-6.28-1.677zM2.338 7.875a4.56 4.56 0 012.394-2.007c0 .042-.003.114-.003.164v5.645a.788.788 0 00.4.688l5.964 3.443-2.064 1.192a.075.075 0 01-.071.006L4.032 14.16a4.6 4.6 0 01-1.694-6.284zM18.93 11.99l-5.965-3.443 2.065-1.192a.074.074 0 01.07-.006l4.927 2.844a4.588 4.588 0 01-.71 8.282v-5.797a.793.793 0 00-.387-.688zm2.056-3.08c-.037-.022-.1-.06-.144-.084L15.96 6.004a.795.795 0 00-.79 0L9.205 9.448V7.064a.073.073 0 01.03-.063l4.925-2.843a4.591 4.591 0 016.826 4.752zM8.114 12.544L6.05 11.352a.073.073 0 01-.04-.057V5.59a4.59 4.59 0 017.533-3.523c-.037.02-.102.055-.144.08L8.514 4.97a.794.794 0 00-.4.688v6.886zm1.12-2.418l2.657-1.534 2.656 1.534v3.068l-2.656 1.534-2.657-1.534V10.126z" />
            </svg>
            <span data-label>Open in ChatGPT</span>
          </button>}

        {show('cursor') && <button onClick={e => handleClick('cursor', e)} data-copied="Copied! Paste in Composer" className={`${buttonBase}`}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
              <path d="M3.147 2.245a.6.6 0 01.652-.054l17.4 9.6a.6.6 0 01.014 1.046l-6.9 4.027-4.182 5.178a.6.6 0 01-1.075-.232L3.013 2.858a.6.6 0 01.134-.613zM10.17 15.2l3.563-2.08L5.34 4.44l4.83 10.76zm.894 1.09l-1.1 1.362 1.357 4.58 2.83-3.504-3.087-2.438z" />
            </svg>
            <span data-label>Copy for Cursor</span>
          </button>}

        {show('vscode') && <button onClick={e => handleClick('vscode', e)} data-copied="Copied! Paste in Copilot Chat" className={`${buttonBase}`}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
              <path d="M17.583 2.603l-5.402 4.914L6.968 3.26 4.2 4.86v14.28l2.768 1.6 5.213-4.257 5.402 4.914L21.6 19.2V4.8l-4.017-2.197zM17.4 17.063l-4.392-3.994 4.392-3.994v7.988zM6.6 15.674V8.326l3.695 3.674L6.6 15.674z" />
            </svg>
            <span data-label>Copy for Copilot</span>
          </button>}

        {show('claude-code') && <button onClick={e => handleClick('claude-code', e)} data-copied="Copied! Paste in Claude Code" className={`${buttonBase}`}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
              <polyline points="4 17 10 11 4 5" />
              <line x1="12" y1="19" x2="20" y2="19" />
            </svg>
            <span data-label>Copy for Claude Code</span>
          </button>}
      </div>
    </div>;
};

export const llmPrompt = `Build a complete, runnable Next.js application that integrates Rye's Universal Checkout API to let users purchase any product by URL from Amazon, Shopify, or other merchants. Use the official Rye TypeScript SDK (checkout-intents) for all API calls.

## What Rye Does
Rye is a commerce API that lets you sell products from any merchant (Amazon, Shopify, etc.) in your app. You provide a product URL and buyer details, Rye fetches pricing/shipping from the merchant, and then you confirm with a payment token to place the order.

## Architecture
IMPORTANT: All Rye SDK calls MUST happen server-side. Never import or use the checkout-intents SDK in client components — the API key must stay on the server.
- Frontend (client components): Form UI, status display. Calls internal Next.js API routes via fetch.
- Backend (Next.js Route Handlers in app/api/): Uses the checkout-intents SDK to talk to Rye. The API key never leaves the server.

## SDK Setup (server-side only)
Install: npm install checkout-intents
Environment variables (server-side, not prefixed with NEXT_PUBLIC_):
  CHECKOUT_INTENTS_API_KEY — the SDK reads this by default
  CHECKOUT_INTENTS_BASE_URL=https://staging.api.rye.com (for staging)

In a server-side file (e.g. lib/rye.ts or an API route):
import CheckoutIntents from 'checkout-intents';
const client = new CheckoutIntents(); // reads CHECKOUT_INTENTS_API_KEY from env

## API Route Structure
app/api/checkout/create-intent/route.ts  — POST: receives buyer + productUrl from frontend, calls SDK, returns intent
app/api/checkout/get-intent/route.ts     — GET: receives intent id, calls SDK, returns current state
app/api/checkout/confirm-intent/route.ts — POST: receives intent id + stripeToken, calls SDK, returns result

## Checkout Flow Using SDK (Two-Phase, server-side)

### Phase 1: Create intent and wait for offer (in API route)
const intent = await client.checkoutIntents.createAndPoll({
  buyer: {
    firstName: 'John', lastName: 'Doe',
    email: 'john.doe@example.com', phone: '212-333-2121',
    address1: '123 Main St', address2: 'Apt 1',
    city: 'New York', province: 'NY',
    postalCode: '10001', country: 'US',
  },
  productUrl: 'https://flybyjing.com/collections/shop/products/sichuan-chili-crisp',
  quantity: 1,
});
// createAndPoll() automatically polls until state is "awaiting_confirmation" or "failed"
// intent.offer.cost has: subtotal, tax, total (each with amountSubunits and currencyCode)
// intent.offer.shipping has: availableOptions (id, cost), selectedOptionId

### Phase 2: Confirm with payment and wait for completion (in API route)
const completed = await client.checkoutIntents.confirmAndPoll(intent.id, {
  paymentMethod: { stripeToken: 'tok_visa', type: 'stripe_token' },
});
// confirmAndPoll() automatically polls until state is "completed" or "failed"
// completed.state === 'completed' means order placed successfully

### Other useful SDK methods
- client.checkoutIntents.create(params) — create without polling
- client.checkoutIntents.retrieve(id) — get current state
- client.checkoutIntents.confirm(id, params) — confirm without polling
- client.checkoutIntents.pollUntilAwaitingConfirmation(id) — poll an existing intent
- client.checkoutIntents.pollUntilCompleted(id) — poll after confirm
- client.products.lookup({ url }) — look up product details by URL

### Error handling
import CheckoutIntents, { PollTimeoutError } from 'checkout-intents';
try { ... } catch (error) {
  if (error instanceof PollTimeoutError) { /* polling timed out */ }
  if (error instanceof CheckoutIntents.APIError) { /* API error with status, message */ }
}
If intent.state === 'failed', check intent.failureReason.code and intent.failureReason.message.

## Important Notes
- Test payment token: tok_visa (Stripe test token, works in staging)
- US shipping addresses only
- Polling helpers accept options: { pollIntervalMs: 5000, maxAttempts: 120 }

## App Requirements
- Next.js App Router with TypeScript and Tailwind CSS
- Use the checkout-intents SDK for ALL Rye API calls (do not use raw fetch)
- ALL SDK usage must be in server-side code (Route Handlers or Server Actions) — never in client components
- CHECKOUT_INTENTS_API_KEY must never be exposed to the browser
- Frontend client components call internal /api/ routes, which use the SDK server-side
- A form for: product URL, buyer details (name, email, phone, address), quantity
- Show real-time order status: creating → retrieving offer → awaiting confirmation (show pricing) → confirming → completed/failed
- Display offer details (subtotal, shipping, tax, total) before the user confirms
- Handle error states and show failureReason if the order fails
- Environment variables (server-side): CHECKOUT_INTENTS_API_KEY, CHECKOUT_INTENTS_BASE_URL
- Include a README with setup instructions

Generate all files needed to run the app. Make sure the .gitignore includes .env and .env.* so secrets are never committed to version control. After generating the code, ask the user for their Rye API key so you can update the .env or .env.local file with the actual CHECKOUT_INTENTS_API_KEY value. Also confirm which environment they want to use (staging or production) so you can set CHECKOUT_INTENTS_BASE_URL accordingly.`;

<OpenWithLLM prompt={llmPrompt} />

## See Rye in Action

Watch a complete order flow — from product URL to purchase confirmation — all without leaving your app.

<Card title img="https://mintcdn.com/rye-35/OSC3sC2UDk1Bocsy/images/order-flow.gif?s=d317148c715620db4075c35e31126b97" width="1512" height="980" data-path="images/order-flow.gif" />

## Step 1: Create a Rye Account

Create a [Rye staging account](https://staging.console.rye.com/register) to get an API key and submit a test order.

## Step 2: Get Your API Key

Go to the [Account tab in your Rye staging account](https://staging.console.rye.com/account), and copy the **Staging API Key**.

Set it as an environment variable:

```bash theme={null}
export RYE_API_KEY="YOUR_API_KEY"
```

## Step 3: Create a Checkout Intent

Send a `POST` request to `/api/v1/checkout-intents` with the product URL and buyer identity.

<CodeGroup>
  ```bash curl theme={null}
  curl --request POST \
    --url https://staging.api.rye.com/api/v1/checkout-intents \
    --header "Authorization: Basic $RYE_API_KEY" \
    --header 'Content-Type: application/json' \
    --data '{
      "buyer": {
        "postalCode": "10001",
        "country": "US",
        "province": "NY",
        "city": "New York",
        "address2": "Apt 1",
        "address1": "123 Main St",
        "phone": "212-333-2121",
        "email": "john.doe@example.com",
        "lastName": "Doe",
        "firstName": "John"
      },
      "productUrl": "https://flybyjing.com/collections/shop/products/the-big-boi",
      "quantity": "1"
    }'
  ```

  ```javascript TypeScript SDK theme={null}
  import CheckoutIntents from 'checkout-intents';

  const client = new CheckoutIntents({
    apiKey: process.env['RYE_API_KEY'],
  });

  const checkoutIntent = await client.checkoutIntents.create({
    buyer: {
      address1: '123 Main St',
      city: 'New York',
      country: 'United States',
      email: 'john.doe@example.com',
      firstName: 'John',
      lastName: 'Doe',
      phone: '212-333-2121',
      postalCode: '10001',
      province: 'NY',
    },
    productUrl: 'https://flybyjing.com/collections/shop/products/the-big-boi',
    quantity: 1,
  });
  ```

  ```python Python SDK theme={null}
  import os
  from checkout_intents import CheckoutIntents

  api_key = os.environ["RYE_API_KEY"]

  client = CheckoutIntents(api_key)

  checkout_intent = client.checkout_intents.create(
      buyer={
          "address1": "123 Main St",
          "city": "New York",
          "country": "US",
          "email": "john.doe@example.com",
          "first_name": "John",
          "last_name": "Doe",
          "phone": "212-333-2121",
          "postal_code": "10001",
          "province": "NY",
      },
      product_url="https://flybyjing.com/collections/shop/products/the-big-boi",
      quantity=1,
  )
  ```

  ```java Java SDK theme={null}
  import com.rye.client.CheckoutIntentsClient;
  import com.rye.client.okhttp.CheckoutIntentsOkHttpClient;
  import com.rye.models.checkoutintents.Buyer;
  import com.rye.models.checkoutintents.CheckoutIntent;
  import com.rye.models.checkoutintents.CheckoutIntentCreateParams;

  CheckoutIntentsClient client = CheckoutIntentsOkHttpClient.fromEnv();

  CheckoutIntentCreateParams params = CheckoutIntentCreateParams.builder()
      .buyer(Buyer.builder()
          .address1("123 Main St")
          .city("New York")
          .country("US")
          .email("john.doe@example.com")
          .firstName("John")
          .lastName("Doe")
          .phone("212-333-2121")
          .postalCode("10001")
          .province("NY")
          .build())
      .productUrl("https://flybyjing.com/collections/shop/products/the-big-boi")
      .quantity(1)
      .build();

  CheckoutIntent checkoutIntent = client.checkoutIntents().create(params);
  ```

  ```ruby Ruby SDK theme={null}
  require "checkout_intents"

  client = CheckoutIntents::Client.new(
    api_key: ENV["RYE_API_KEY"]
  )

  checkout_intent = client.checkout_intents.create(
    buyer: {
      address1: "123 Main St",
      city: "New York",
      country: "US",
      email: "john.doe@example.com",
      firstName: "John",
      lastName: "Doe",
      phone: "212-333-2121",
      postalCode: "10001",
      province: "NY"
    },
    product_url: "https://flybyjing.com/collections/shop/products/the-big-boi",
    quantity: 1
  )
  ```
</CodeGroup>

<Note>
  You can send orders to Amazon, Shopify, or other merchants by simply changing the product URL. Example test URLs:

  * [https://www.raakachocolate.com/products/blueberry-lemon?variant=41038993227863](https://www.raakachocolate.com/products/blueberry-lemon?variant=41038993227863)
  * [https://www.amazon.com/Apple-MX532LL-A-AirTag/dp/B0CWXNS552/](https://www.amazon.com/Apple-MX532LL-A-AirTag/dp/B0CWXNS552/)
</Note>

<Warning>
  Orders can only be shipped to **U.S. addresses**. International shipping is not yet supported. Using a non-US address will cause the checkout intent to fail.
</Warning>

## Step 4: Poll for `awaiting_confirmation`

After creating the intent, poll the `/api/v1/checkout-intents/{id}` endpoint with a `GET` request until the state is `awaiting_confirmation`. Use the `id` from the previous step.

<CodeGroup>
  ```bash curl theme={null}
  curl --request GET \
    --url https://staging.api.rye.com/api/v1/checkout-intents/{id} \
    --header "Authorization: Basic $RYE_API_KEY"
  ```

  ```javascript TypeScript SDK theme={null}
  const checkoutIntent = await client.checkoutIntents.retrieve('id');
  ```

  ```python Python SDK theme={null}
  checkout_intent = client.checkout_intents.retrieve("id")
  ```

  ```java Java SDK theme={null}
  CheckoutIntent checkoutIntent = client.checkoutIntents().retrieve("id");
  ```

  ```ruby Ruby SDK theme={null}
  checkout_intent = client.checkout_intents.retrieve("id")
  ```
</CodeGroup>

Example response:

```json theme={null}
{
  "state": "awaiting_confirmation"
}
```

Fetching an offer from the merchant is asynchronous. Always poll the `GET` endpoint for the latest state of the intent.

<Tip>
  Use the `failureReason` field to display helpful error messages to users.

  Use the SDK’s `createAndPoll()` helper method to complete steps 3 and 4 in a single call.
</Tip>

## Step 5: Confirm Final Pricing

Before proceeding to payment, inspect the latest checkout intent response to confirm:

* Shipping options and costs
* Taxes
* Total cost
* Offer availability

Example response:

```bash theme={null}
{
  "id": "ci_4197e51f48290517639402856173049",
  "createdAt": "2025-10-14T21:38:52.062Z",
  "productUrl": "https://flybyjing.com/collections/shop/products/the-big-boi",
  ...
  "quantity": 1,
  "variantSelections": null,
  "state": "awaiting_confirmation",
  "offer": {
    "cost": {
      "subtotal": {
        "amountSubunits": 1500,
        "currencyCode": "USD"
      },
      "tax": {
        "amountSubunits": 0,
        "currencyCode": "USD"
      },
      "total": {
        "amountSubunits": 2300,
        "currencyCode": "USD"
      }
    },
    "shipping": {
      "availableOptions": [
        {
          "id": "8-Flat Rate Shipping",
          "cost": {
            "amountSubunits": 800,
            "currencyCode": "USD"
          }
        }
      ],
      "selectedOptionId": "8-Flat Rate Shipping"
    }
  }
}
```

Ensure your UI reflects the full cost to the user and allows them to confirm or adjust details if needed.

## Step 6: Generate a Card Token

In staging, you can use the test token `tok_visa` to place an order.

Alternatively, follow [these steps](/api-v2/payment-providers/stripe) to build a simple React app that generates tokens with Stripe Elements.

<Info>This guide uses Stripe, but Rye supports other payment providers too. See [Payment Providers](/api-v2/payment-providers) for all options.</Info>

## Step 7: Confirm with Payment

Once the user approves the final cost, confirm the intent with their payment method:

<CodeGroup>
  ```bash curl theme={null}
  curl --request POST \
    --url https://staging.api.rye.com/api/v1/checkout-intents/{id}/confirm \
    --header "Authorization: Basic $RYE_API_KEY" \
    --header 'Content-Type: application/json' \
    --data '{
      "paymentMethod": {
        "stripeToken": "tok_visa",
        "type": "stripe_token"
      }
    }'
  ```

  ```javascript TypeScript SDK theme={null}
  const checkoutIntent = await client.checkoutIntents.confirm('id', {
    paymentMethod: { stripeToken: 'tok_visa', type: 'stripe_token' },
  });
  ```

  ```python Python SDK theme={null}
  checkout_intent = client.checkout_intents.confirm(
      "id",
      payment_method={
          "stripe_token": "tok_visa",
          "type": "stripe_token",
      },
  )
  ```

  ```java Java SDK theme={null}
  import com.rye.models.checkoutintents.CheckoutIntentConfirmParams;
  import com.rye.models.checkoutintents.PaymentMethod;

  CheckoutIntentConfirmParams confirmParams = CheckoutIntentConfirmParams.builder()
      .paymentMethod(PaymentMethod.StripeTokenPaymentMethod.builder()
          .stripeToken("tok_visa")
          .type(PaymentMethod.StripeTokenPaymentMethod.Type.STRIPE_TOKEN)
          .build())
      .build();

  CheckoutIntent checkoutIntent = client.checkoutIntents().confirm("id", confirmParams);
  ```

  ```ruby Ruby SDK theme={null}
  checkout_intent = client.checkout_intents.confirm(
    "id",
    payment_method: { stripe_token: "tok_visa", type: "stripe_token" }
  )
  ```
</CodeGroup>

Placing an order is asynchronous. Always poll the `GET` endpoint after confirming to check the state of the intent.

Once in a terminal state (`completed` or `failed`), the intent is finished.

<Warning>
  Checkout intents cannot be updated once created. If buyer details (e.g. shipping address) change, create a new checkout intent.
</Warning>

## Step 8: Poll for Final State

After confirming, poll the `GET` endpoint again until the intent reaches a terminal state:

* `completed`: order placed successfully
* `failed`: something went wrong (e.g. out of stock, expired)

<CodeGroup>
  ```bash curl theme={null}
  curl --request GET \
    --url https://staging.api.rye.com/api/v1/checkout-intents/{id} \
    --header "Authorization: Basic $RYE_API_KEY"
  ```

  ```javascript TypeScript SDK theme={null}
  const checkoutIntent = await client.checkoutIntents.retrieve('id');
  ```

  ```python Python SDK theme={null}
  checkout_intent = client.checkout_intents.retrieve("id")
  ```

  ```java Java SDK theme={null}
  CheckoutIntent checkoutIntent = client.checkoutIntents().retrieve("id");
  ```

  ```ruby Ruby SDK theme={null}
  checkout_intent = client.checkout_intents.retrieve("id")
  ```
</CodeGroup>

Example responses:

```json theme={null}
{ "state": "completed" }
```

```json theme={null}
{
  "state": "failed",
  "failureReason": {
    "code": "product_out_of_stock",
    "message": "The item is no longer available."
  }
}
```

<Tip>
  Check the [Rye console](https://staging.console.rye.com/checkout-intents) to view test orders.

  Use the SDK’s `confirmAndPoll()` helper method to complete steps 7 and 8 in a single call.
</Tip>

<Note>
  Rye does not provide post-purchase tracking or webhooks. Tracking and order updates are sent directly to the buyer's email address.
</Note>

## Next Steps

Congrats — you just submitted your first Rye order!

Next, check out the [API Comparison](/api-v2/api-comparison) guide to learn about the differences between the Universal Checkout API and the Sync API.
