Orders API

    Use the Orders API to sell and organize your products through Stripe.

    If you’re dealing with physical or digital products, the Orders API helps you manage pricing and inventory, automatically calculate shipping costs and taxes, and create and pay for orders. It’s based on three primary objects:

    • Product, a blanket representation of an item your business sells (for instance, “2015 Limited Edition T-shirt”).
    • SKU (Stock Keeping Unit), a specific product variation, taking into account any combination of attributes and cost (for instance, size, color, currency, cost).
    • Order, a combination of customer information and the SKUs they want to purchase.

    Stripe lets you manage pricing and inventory, automatically calculate shipping costs and taxes, and create and pay for orders. To get started with orders, you should define products and SKUs and configure shipping and tax integrations. Once your inventory is set up, you can create and pay for orders.

    Although all of this functionality can be implemented using the Dashboard alone, this guide focuses on developer usage of the Orders API. Developers can also read the Orders Guide for additional information, including best practices and using webhooks.

    When to use orders

    Orders integrate nicely with other parts of the Stripe API that you might already be familiar with. For example, paying an order creates a Charge object. Similarly, returning an order will create a refund for all or part of that charge. Orders support additional features beyond basic charges that you might find helpful:

    • Calculate taxes due on orders via Avalara, TaxJar, or Taxamo
    • Retrieve shipping rates from USPS, FedEx, and more using EasyPost or Shippo
    • Keep track of fulfilled orders and seamlessly handle returns
    • Import products from a Google or LinkShare product feed

    Using the Orders API would be a good idea if any of the following apply to you:

    • You need to calculate taxes or shipping for the products you are selling
    • You sell physical goods than can be shipped and returned by customers

    On the other hand, there are some cases where other Stripe products would be easier to use:

    • If you want to charge customers on a recurring basis, subscriptions let you do that easily
    • If you are selling a variable-rate service (like a Lyft ride), charges give you more flexibility
    • If you already have an inventory, tax, and shipping system, you may not need the extra features that Stripe orders provide

    Define products and SKUs

    You can start out by creating your products and SKUs in the Dashboard. Products can be physical (things you ship) or digital (things your customers download). (See the best practices for examples and additional tips.) You can also easily create products and SKUs programmatically:

    curl https://api.stripe.com/v1/products \
       -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
       -d name="2015 Limited Edition T-shirt" \
       -d description="Super awesome, one-of-a-kind t-shirt" \
       -d attributes[]=size \
       -d attributes[]=gender \
       -d attributes[]=color
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"
    
    # Create the product
    Stripe::Product.create(
      :name => '2015 Limited Edition T-shirt',
      :description => 'Super awesome, one-of-a-kind t-shirt',
      # These are the characteristics of the product that SKUs provide values for
      :attributes => ['size', 'gender', 'color']
    )
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"
    
    # Create the product
    stripe.Product.create(
      name='2015 Limited Edition T-shirt',
      description='Super awesome, one-of-a-kind t-shirt',
      # These are the characteristics of the product that SKUs provide values for
      attributes=['size', 'gender', 'color']
    )
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    \Stripe\Stripe::setApiKey("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    // Create the product
    \Stripe\Product::create(array(
      "name" => '2015 Limited Edition T-shirt',
      "description" => "Super awesome, one-of-a-kind t-shirt",
      // These are the characteristics of the product that SKUs provide values for
      "attributes" => array("size", "gender", "color")
    ));
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.apiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2";
    
    // Create the product
    Map<String, Object> productParams = new HashMap<String, Object>();
    productParams.put("name", "2015 Limited Edition T-shirt");
    productParams.put("description", "Super awesome, one-of-a-kind t-shirt");
    // These are the characteristics of the product that SKUs provide values for
    List<String> attributesParams = new LinkedList<String>();
    attributesParams.add("size");
    attributesParams.add("gender");
    productParams.put("attributes", attributesParams);
    
    Product.create(productParams);
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    var stripe = require("stripe")("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    // Create the product
    stripe.products.create({
      name: '2015 Limited Edition T-shirt',
      description: 'Super awesome, one-of-a-kind t-shirt',
      // These are the characteristics of the product that SKUs provide values for
      attributes: ['size', 'gender', 'color']
    }, function(err, product) {
      // asynchronously called
    });
    

    Products can have associated images, descriptions, and more. The attributes property is how a product defines the features that can be set on individual SKUs: the specific versions of the product a customer actually buys. For example, the above code says that the “2015 Limited Edition T-shirt” product comes in different variations for size, gender, and color.

    With a product defined, create specific product variations as SKUs, taking into account all possible combinations of attributes.

    curl https://api.stripe.com/v1/skus \
       -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
       -d product=prod_Bc3i3zYrdJ2TTE \
       -d attributes[size]=Medium \
       -d attributes[gender]=Unisex \
       -d attributes[color]=Cyan \
       -d price=1500 \
       -d currency=usd \
       -d inventory[type]=finite \
       -d inventory[quantity]=500
    curl https://api.stripe.com/v1/skus \
       -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
       -d product=prod_Bc3i3zYrdJ2TTE \
       -d attributes[size]=Large \
       -d attributes[gender]=Unisex \
       -d attributes[color]=Cyan \
       -d price=1500 \
       -d currency=usd \
       -d inventory[type]=finite \
       -d inventory[quantity]=400
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"
    
    Stripe::SKU.create(
      :product => 'prod_Bc3i3zYrdJ2TTE',
      :attributes => {
        'size' => 'Medium',
        'gender' => 'Unisex',
        'color' => 'Cyan',
      },
      :price => 1500,
      :currency => 'usd',
      :inventory => {
        'type' => 'finite',
        'quantity' => 500
      }
    )
    Stripe::SKU.create(
      :product => 'prod_Bc3i3zYrdJ2TTE',
      :attributes => {
        'size' => 'Large',
        'gender' => 'Unisex',
        'color' => 'Cyan'
      },
      :price => 1500,
      :currency => 'usd',
      :inventory => {
        'type' => 'finite',
        'quantity' => 400
      }
    )
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"
    
    stripe.SKU.create(
      product='prod_Bc3i3zYrdJ2TTE',
      attributes={'size': 'Medium', 'gender': 'Unisex', 'color': 'Cyan'},
      price=1500,
      currency='usd',
      inventory={'type': 'finite', 'quantity': 500}
    )
    stripe.SKU.create(
      product='prod_Bc3i3zYrdJ2TTE',
      attributes={'size': 'Large', 'gender': 'Unisex', 'color': 'Cyan'},
      price=1500,
      currency='usd',
      inventory={'type': 'finite', 'quantity': 400}
    )
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    \Stripe\Stripe::setApiKey("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    \Stripe\SKU::create(array(
      "product" => "prod_Bc3i3zYrdJ2TTE",
      "attributes" => array(
        "size" => "Medium",
        "gender" => "Unisex",
        "color" => "Cyan"
      ),
      "price" => 1500,
      "currency" => "usd",
      "inventory" => array(
        "type" => "finite",
        "quantity" => 500
      )
    ));
    \Stripe\SKU::create(array(
      "product" => "prod_Bc3i3zYrdJ2TTE",
      "attributes" => array(
        "size" => "Large",
        "gender" => "Unisex",
        "color" => "Cyan"
      ),
      "price" => 1500,
      "currency" => "usd",
      "inventory" => array(
        "type" => "finite",
        "quantity" => 400
      )
    ));
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.apiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2";
    
    Map<String, Object> skuParams = new HashMap<String, Object>();
    skuParams.put("product", "prod_Bc3i3zYrdJ2TTE");
    Map<String, Object> attributesParams = new HashMap<String, Object>();
    attributesParams.put("size", "Medium");
    attributesParams.put("gender", "Unisex");
    attributesParams.put("color", "Cyan");
    skuParams.put("attributes", attributesParams);
    skuParams.put("price", 1500);
    skuParams.put("currency", "usd");
    Map<String, Object> inventoryParams = new HashMap<String, Object>();
    inventoryParams.put("type", "finite");
    inventoryParams.put("quantity", 500);
    skuParams.put("inventory", inventoryParams);
    
    SKU.create(skuParams);
    
    skuParams.clear();
    skuParams.put("product", "prod_Bc3i3zYrdJ2TTE");
    attributesParams.clear();
    attributesParams.put("size", "Large");
    attributesParams.put("gender", "Unisex");
    attributesParams.put("color", "Cyan");
    skuParams.put("attributes", attributesParams);
    skuParams.put("price", 1500);
    skuParams.put("currency", "usd");
    inventoryParams.clear();
    inventoryParams.put("type", "finite");
    inventoryParams.put("quantity", 400);
    skuParams.put("inventory", inventoryParams);
    
    SKU.create(skuParams);
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    var stripe = require("stripe")("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    stripe.skus.create({
      product: 'prod_Bc3i3zYrdJ2TTE',
      attributes: {'size': 'Medium', 'gender': 'Unisex', 'color': 'Cyan'},
      price: 1500,
      currency: 'usd',
      inventory: {'type': 'finite', 'quantity': 500}
    }, function(err, sku) {
      // asynchronously called
    });
    stripe.skus.create({
      product: 'prod_Bc3i3zYrdJ2TTE',
      attributes: {'size': 'Large', 'gender': 'Unisex', 'color': 'Cyan'},
      price: 1500,
      currency: 'usd',
      inventory: {'type': 'finite', 'quantity': 400}
    }, function(err, sku) {
      // asynchronously called
    });
    

    The above code creates two different SKUs—variants on a product, differentiated by size and price. You will normally have exponentially more SKUs than products. If the “2015 Limited Edition T-shirt” came in three sizes—small, medium, and large—and in two colors—cyan and magenta, there would be at least 6 SKUs representing it.

    Configure shipping and tax handling

    Real-world orders involve not only the cost of the items being purchased, but also shipping costs and taxes. Stripe can automatically and dynamically add these costs to your orders.

    Configure your shipping and tax preferences in your Stripe account, by choosing one of three approaches.

    Shipping can be set as:

    • provider: A third-party provider like EasyPost or Shippo which will provide the shipping rates dynamically
    • flat_rate: One or more fixed-cost options like Standard, Express, and Overnight shipping. You can even opt to waive the shipping cost above a certain order total.
    • free: No additional cost, the default

    Tax can be set as:

    • provider: A third-party provider like Avalara, TaxJar, or Taxamo which will provide the tax amount dynamically
    • percentage: A flat additional cost, as a percent of the order total, before shipping
    • included: No additional cost, the default

    Both shipping and taxes can also be set to callback. If you wish to calculate shipping and taxes yourself, provide an endpoint on your own server that Stripe will reach out to in real-time to retrieve these costs. This can be helpful if you want to use the Orders API but have an existing system for shipping and taxes or if you want to sell through an application.

    Create and pay for orders

    With your products and SKUs already on Stripe, it is time to start creating orders. When using orders, your checkout flow will most likely look something like the following:

    1. A customer picks one or more items (SKUs) that they want to purchase
    2. You create an order containing those items to retrieve tax and shipping costs from Stripe
    3. The customer provides you with payment credentials that you use to pay the order

    We will focus on the two last steps here. To create an order, specify the SKUs in the order as well as the customer’s shipping address:

    curl https://api.stripe.com/v1/orders \
       -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
       -d currency=usd \
       -d email="jenny@example.com" \
       -d items[][type]=sku \
       -d items[][parent]=sku_Bc2jyTuA1adjoY \
       -d items[][quantity]=2 \
       -d shipping[name]="Jenny Rosen" \
       -d shipping[address][line1]="1234 Main Street" \
       -d shipping[address][city]=Anytown \
       -d shipping[address][country]=US \
       -d shipping[address][postal_code]=123456
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"
    
    order = Stripe::Order.create(
      :currency => 'usd',
      :email => 'jenny@example.com',
      :items => [
        {
          :type => 'sku',
          :parent => 'sku_Bc2jyTuA1adjoY',
          :quantity => 2,
        }
      ],
      :shipping => {
        :name => 'Jenny Rosen',
        :address => {
          :line1 => '1234 Main Street',
          :city => 'Anytown',
          :country => 'US',
          :postal_code => '123456'
        }
      },
    )
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"
    
    order = stripe.Order.create(
      currency = 'usd',
      email = 'jenny@example.com',
      items = [
        {
          "type":'sku',
          "parent":'sku_Bc2jyTuA1adjoY',
          "quantity": 2,
        }
      ],
      shipping = {
        "name":'Jenny Rosen',
        "address":{
          "line1":'1234 Main Street',
          "city":'Anytown',
          "country":'US',
          "postal_code":'123456'
        }
      },
    )
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    \Stripe\Stripe::setApiKey("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    $order = \Stripe\Order::create(array(
      "currency" => "usd",
      "email" => "jenny@example.com",
      "items" => array(
        array(
          "type" => "sku",
          "parent" => "sku_Bc2jyTuA1adjoY",
          "quantity" => 2,
        )
      ),
      "shipping" => array(
        "name" => "Jenny Rosen",
        "address" => array(
          "line1" => "1234 Main Street",
          "city" => "Anytown",
          "country" => "US",
          "postal_code" => "123456"
        )
      ),
    ));
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.apiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2";
    
    Map<String, Object> orderParams = new HashMap<String, Object>();
    orderParams.put("currency", "usd");
    orderParams.put("email", "jenny@example.com");
    List<Object> itemsParams = new LinkedList<Object>();
    Map<String, String> item1 = new HashMap<String, String>();
    item1.put("type", "sku");
    item1.put("parent", "sku_Bc2jyTuA1adjoY");
    item1.put("quantity", "2");
    itemsParams.add(item1);
    orderParams.put("items", itemsParams);
    Map<String, Object> shippingParams = new HashMap<String, Object>();
    shippingParams.put("name", "Jenny Rosen");
    Map<String, Object> addressParams = new HashMap<String, Object>();
    addressParams.put("line1", "1234 Main Street");
    addressParams.put("city", "Anytown");
    addressParams.put("country", "US");
    addressParams.put("postal_code", "123456");
    shippingParams.put("address", addressParams);
    orderParams.put("shipping", shippingParams);
    
    Order order = Order.create(orderParams, null);
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    var stripe = require("stripe")("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    stripe.orders.create({
      currency: 'usd',
      email: 'jenny@example.com',
      items: [
        {
          type: 'sku',
          parent: 'sku_Bc2jyTuA1adjoY',
          quantity: 2
        }
      ],
      shipping: {
        name: 'Jenny Rosen',
        address: {
          line1: '1234 Main Street',
          city: 'Anytown',
          country: 'US',
          postal_code: '123456'
        }
      }
    }, function(err, order) {
      // asynchronously called
    });
    

    You will receive an order object in the response (some fields omitted for brevity):

    {
      "id": "or_18Q3IaDAu10Yox5RqlL8JnnS",
      "amount": 2172,
      "status": "created",
      "items": [
        {
          "type": "sku",
          "amount": 1500,
          "description": "2015 Limited Edition T-shirt",
          "parent": "sku_Bc2jyTuA1adjoY",
          ...
        },
        {
          "type": "tax",
          "amount": 112,
          "description": "CA STATE TAX (P0000000)",
          "parent": null,
          ...
        },
        {
          "type": "shipping",
          "amount": 560,
          "description": "USPS Priority Mail",
          "parent": "ad989a994218446fbd48978a6ac905b0",
          ...
        }
      ],
      "selected_shipping_method": "0083dfe889534b75bf8ca73aa703e938",
      "shipping_methods": [
        {
          "id": "ad989a994218446fbd48978a6ac905b0",
          "amount": 560,
          "description": "USPS Priority Mail",
          ...
        },
        {
          "id": "db18a419e6f14aba82aa41f2bb9ec08e",
          "amount": 595,
          "description": "USPS Parcel Select",
          ...
        }
      ],
      ..
    }

    When creating an order, Stripe performs the following actions:

    • Verifies that the SKU was still in stock and retrieves its current price
    • Retrieves the taxes due from your tax provider and adds a $1.12 tax line item
    • Retrieves shipping rates from your shipping provider and adds the available shipping methods. The default rate of $5.60 is already included in the order as a shipping line item.
    • Sums up all the line items and packs them into the order object

    You should store the order id in your database and present the customer with the order total of $82.39. When your customer is ready to pay, you can collect their payment details. Then, simply pass the token to Stripe to pay the order:

    curl https://api.stripe.com/v1/orders/or_1BEoeZ2eZvKYlo2C1GPjZzoL/pay \
       -u sk_test_BQokikJOvBiI2HlWgH4olfQ2: \
       -d source="{TOKEN}"
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"
    
    # Get the credit card details submitted by the form
    token = params[:stripeToken]
    
    order = Stripe::Order.retrieve('or_1BEoeZ2eZvKYlo2C1GPjZzoL')
    
    order.pay(:source => token)
    
    # Set your secret key: remember to change this to your live secret key in production
    # See your keys here: https://dashboard.stripe.com/account/apikeys
    stripe.api_key = "sk_test_BQokikJOvBiI2HlWgH4olfQ2"
    
    # Get the credit card details submitted by the form
    token = request.POST['stripeToken']
    
    order = stripe.Order.retrieve('or_1BEoeZ2eZvKYlo2C1GPjZzoL')
    
    order.pay(source=token)
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    \Stripe\Stripe::setApiKey("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    // Get the credit card details submitted by the form
    $token = $_POST['stripeToken'];
    
    $order = \Stripe\Order::retrieve("or_1BEoeZ2eZvKYlo2C1GPjZzoL");
    
    $order->pay(array("source" => $token));
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    Stripe.apiKey = "sk_test_BQokikJOvBiI2HlWgH4olfQ2";
    
    // Get the credit card details submitted by the form
    String token = request.getParameter("stripeToken");
    
    Order order = Order.retrieve("or_1BEoeZ2eZvKYlo2C1GPjZzoL", null);
    
    Map<String, Object> orderParams = new HashMap<String, Object>();
    orderParams.put("source", token);
    
    order.pay(orderParams);
    
    // Set your secret key: remember to change this to your live secret key in production
    // See your keys here: https://dashboard.stripe.com/account/apikeys
    var stripe = require("stripe")("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    
    // Get the credit card details submitted by the form
    var token = request.body.stripeToken; // Using Express
    
    stripe.orders.pay("or_1BEoeZ2eZvKYlo2C1GPjZzoL", {
      source: token
    }, function(err, order) {
      // called asynchronously
    });
    

    Next steps

    Congrats! You've gone through how to use the APIs for products, SKUs and orders. Some things you might want to see next: