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

# Order Product

Place a real product order from Amazon or Walmart, shipped to a US address. By default only free-shipping / Prime items are ordered (freeShipping=true): the vendor is constrained to a free-shipping offer, so shipping is $0 and can't push the charge past the cap, and an item with no free offer is rejected before payment. Set freeShipping=false to allow paid-shipping offers (a flat shipping allowance is then folded into the cap). Pay in USDC from a connected crypto wallet, or in fiat straight from a connected Airwallex balance — whichever wallet you select. You pay the listed item cost plus a tax buffer plus a service fee of $2.50 + 2%; unused headroom between the cap and the retailer's final total is refunded on the same rail you paid from. The product charge never exceeds the authorized cap. Paying from an Airwallex balance is a PREVIEW capability, available on local and dev only — no production org can hold an Airwallex connector, so the fiat rail cannot be selected there. Where it is available it needs maxTotalCents, which is then the all-in total including the service fee, and needs no wallet, chain or gas. Ideal for: automated purchasing, reorder workflows, gifting, buying supplies with crypto or fiat.

![Order Product logo](https://cdn.b3.fun/zinc-logo.png)
Catalog action Integrations wallet Gas

Place a real product order from Amazon or Walmart, shipped to a US address. By default only free-shipping / Prime items are ordered (freeShipping=true): the vendor is constrained to a free-shipping offer, so shipping is $0 and can't push the charge past the cap, and an item with no free offer is rejected before payment. Set freeShipping=false to allow paid-shipping offers (a flat shipping allowance is then folded into the cap). Pay in USDC from a connected crypto wallet, or in fiat straight from a connected Airwallex balance — whichever wallet you select. You pay the listed item cost plus a tax buffer plus a service fee of $2.50 + 2%; unused headroom between the cap and the retailer's final total is refunded on the same rail you paid from. The product charge never exceeds the authorized cap. Paying from an Airwallex balance is a PREVIEW capability, available on local and dev only — no production org can hold an Airwallex connector, so the fiat rail cannot be selected there. Where it is available it needs maxTotalCents, which is then the all-in total including the service fee, and needs no wallet, chain or gas. Ideal for: automated purchasing, reorder workflows, gifting, buying supplies with crypto or fiat.

**Review wallet and value movement**

This action can require a wallet connector, gas, token movement, or an external side effect. Test with simulation or a controlled amount before using it in a live workflow.

## At a Glance

| Field | Value |
| --- | --- |
| Action ID | `order-product` |
| Category | Integrations |
| Connector | `wallet` |
| Requires gas | Yes |
| Funds movement | None declared |
| Tags | `shopping`, `order`, `ecommerce`, `purchase`, `write` |

## Payload Schema

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `productUrl` | `string` | Yes | Product URL to order \(e.g. https://www.amazon.com/dp/B01N5IB20Q or https://www.walmart.com/ip/123456789\). A bare 10-character Amazon ASIN is also accepted. |
| `productTitle` | `string` | No | Optional product title \(from search-products\). Recorded on the vendor order so the order-status page can show the product without a separate product lookup. Not used for ordering. |
| `productImageUrl` | `string` | No | Optional primary product image URL \(from search-products\). Recorded on the vendor order for the order-status page. Not used for ordering. |
| `quantity` | `number` | No | Number of units to order \(1-10\). Default: 1. |
| `itemPriceCents` | `number` | Yes | Current listed per-unit price in integer USD cents \(from search-products or get-product-details\). Used to compute the authorized cap and service fee. |
| `maxTotalCents` | `number` | No | Authorized cap in integer cents. On the USDC rail it caps the PRODUCT \(tax and shipping included\) and the service fee is added on top; omitted, it defaults to the item subtotal plus a 15% headroom buffer. REQUIRED when paying from an Airwallex balance \(a preview rail, local and dev only\), where it is instead the ALL-IN total the order may debit — service fee included — so it is exactly the amount checked against your organization's fiat spend limit. The product charge never exceeds the authorized cap on either rail. |
| `expectedTotalChargeCents` | `number` | No | Optional all-in total, in integer cents, that the caller has already shown someone and had approved. When set, the order is refused before any money moves if the charge this run computes would EXCEED it — so an approved purchase can never cost more than the figure on the card, whichever rail settles it. It is a ceiling only: the charge is always solved from maxTotalCents, which is the field your organization's fiat spend limit measures. |
| `expectedPaymentMethod` | `string` | No | Optional rail that the approval card described. When set, the order is refused before any money moves if the selected wallet settles on the other rail — the amount ceiling cannot stand in for this, because a card priced on the USDC shape shows a HIGHER all-in figure than the fiat rail charges, so a mismatched wallet clears the ceiling while debiting an account the card never named. |
| `shippingAddress` | `object` | Yes | US shipping address for the order. |
| `freeShipping` | `boolean` | No | Require free/Prime shipping for this purchase \(default: true\). When true the order is placed with a free-shipping constraint, so the vendor buys a free/Prime offer and the quoted total holds — shipping can't push the charge past the cap. If the item has no free-shipping offer the order is rejected BEFORE any payment \(nothing is charged\). Set false to allow paid-shipping offers. |
| `chainId` | `number` | No | Chain to pay from in USDC. Supported: 8453 \(Base\), 1 \(Ethereum\), 42161 \(Arbitrum\), 10 \(Optimism\), 137 \(Polygon\). Default: 8453. |
| `simulate` | `boolean` | No | Sandbox/test mode. When true, places a vendor TEST order and SKIPS the on-chain USDC payment \(no real money moves\) — used to exercise the full order flow safely. Requires a configured test key; if none is available the order is refused rather than charged. Default: false \(real order\). |

## Result Schema

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `orderId` | `string` | Yes | Order identifier — use with get-product-order to track status. |
| `status` | `string` | Yes | Order status \(newly placed orders start as 'pending'\). |
| `productUrl` | `string` | Yes | Canonical product URL that was ordered. |
| `quantity` | `number` | Yes | Number of units ordered. |
| `itemPriceCents` | `number` | Yes | Listed per-unit price in integer cents. |
| `itemSubtotalCents` | `number` | Yes | itemPriceCents * quantity. |
| `productMaxCents` | `number` | Yes | Authorized product cap in cents \(incl. tax/shipping headroom\). |
| `serviceFeeCents` | `number` | Yes | Service fee charged in cents. |
| `totalChargeCents` | `number` | Yes | Total USDC charge in cents \(cap + service fee\). |
| `totalChargeUsd` | `number` | Yes | Total USDC charge in USD \(2 decimal places\). |
| `paymentTransactionHash` | `string \| null` | Yes | USDC payment transaction hash. Null in simulation, and null when paid from an Airwallex balance. |
| `paymentChainId` | `number \| null` | Yes | Chain the USDC payment was made on. Null when paid from an Airwallex balance, which touches no chain. |
| `paymentMethod` | `string` | Yes | Which rail settled the payment: an on-chain USDC transfer, or a debit from the connected Airwallex balance. |
| `paymentReference` | `string \| null` | Yes | The payment's identity on whichever rail settled it — a transaction hash on-chain, an Airwallex transfer id in fiat. Null in simulation. |
| `refundBeneficiaryId` | `string \| null` | Yes | Airwallex beneficiary, registered on the platform treasury at payment time, that a refund is paid back to over bank rails. Null on the USDC rail, where refunds go on-chain to the paying wallet. |
| `refundTransferMethod` | `string \| null` | Yes | Rail the refund beneficiary was registered for — LOCAL where the account published a routing code, SWIFT otherwise. Null on the USDC rail. |
| `shipToSummary` | `string` | Yes | Short shipping destination summary \(e.g. 'Jane Smith, Seattle, WA 98101'\). |

## Examples

**Workflow node**

```json
{
  "type": "order-product",
  "payload": {
    "productUrl": "https://example.com/webhook",
    "itemPriceCents": 1,
    "shippingAddress": {
      "firstName": "example-firstName",
      "lastName": "example-lastName",
      "addressLine1": "example-addressLine1",
      "city": "example-city",
      "state": "example-state",
      "zipCode": "98101",
      "phoneNumber": "example-phoneNumber"
    }
  },
  "children": [],
  "connector": {
    "type": "wallet",
    "id": "conn_wallet"
  }
}
```
  **Test with API**

```bash
curl -X POST "https://api.b3os.org/v1/actions/order-product/test" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "inputs": {
    "productUrl": "https://example.com/webhook",
    "itemPriceCents": 1,
    "shippingAddress": {
      "firstName": "example-firstName",
      "lastName": "example-lastName",
      "addressLine1": "example-addressLine1",
      "city": "example-city",
      "state": "example-state",
      "zipCode": "98101",
      "phoneNumber": "example-phoneNumber"
    }
  }
}'
```

**Use expressions for dynamic values**

Payload fields can use workflow expressions such as `{{$trigger.body.amount}}`, `{{$nodes.fetch.result.price}}`, and `{{$props.asset}}` when the value should come from a trigger, prior node, or reusable workflow prop.