# Custom Checkout with Stripe Elements

## Overview

To create a custom checkout session with taxes calculated using the Sphere API, follow these steps:

1. Call the Sphere Tax Calculation API to retrieve applicable tax rates.
2. Create Stripe Tax Rates corresponding to each rate provided by Sphere. For details, refer to [Stripe’s Tax Rate Documentation](https://docs.stripe.com/api/tax_rates/create).
3. Develop a custom payment form using Stripe Elements, either for one-time payments (Step 3a) or subscriptions (Step 3b), and link the Stripe tax rates obtained from the Sphere API calculations.

Stripe Elements are pre-built UI components provided by Stripe for securely collecting payment information, such as card details and payment method preferences. These components are customizable to match your website’s design and work seamlessly with Stripe’s APIs for secure payment processing. For detailed guidance, refer to[ Stripe Elements Documentation](https://docs.stripe.com/payments/elements).

***

## **Step 1: Call the Sphere Tax Calculation API** <a href="#step-1-call-the-sphere-tax-calculation-api" id="step-1-call-the-sphere-tax-calculation-api"></a>

Make a **POST** request to the Sphere Tax Calculation API to retrieve applicable tax rates for a given customer address and product.

**Endpoint:** <https://server.getsphere.com/tax_api/calculate_tax>

**Request Headers:**

* **Header Key:** X-API-KEY
* **Header Value:** YOUR\_API\_KEY

**Sample Request:**

```sh
curl -X \
 POST https://server.getsphere.com/tax_api/calculate_tax \
-H \
 "Content-Type: application/json" \
-H \
 "X-API-KEY: sph_api_key" \
-d '{
  "customer_address": {
    "address1": "Investors Boulevard",
    "city": "Myrtle Beach",
    "state": "SC",
    "postal_code": "29579",
    "country": "US"
  },
  "line_items": [
    {
      "amount": 10000,
      "product_id": "prod_RArEhwhXLfX5jF",
      "discount_amount": 0,
      "tax_inclusive": false
    }
  ],
  "currency": "usd"
}'

```

**Sample Response:**

```json
{
  "lines": [
    {
      "id": "prod_RArEhwhXLfX5jF",
      "tax_amounts": [
        {
          "amount": 900,
          "taxable_amount": 10000,
          "tax_rate": {
            "percentage": 6.0,
            "inclusive": false,
            "display_name": "Sales Tax",
            "jurisdiction": "South Carolina",
            "country": "US",
            "state": "SC",
            "tax_type": "sales_tax"
          }
        }
      ]
    }
  ],
  "sphere_tax_calculation_id": "cfd1e35a-ccb8-4bf1-86ed-49e332be220b"
}
```

***

## **Step 2: Create Stripe Tax Rate Objects**

For each tax rate returned by the Sphere Api, create a corresponding Stripe Tax Rate object. You’ll need to pass Stripe the tax details provided by the Sphere Api. [Stripe’s Tax Rate documentation](https://docs.stripe.com/api/tax_rates/create).&#x20;

**Note: This step is optional for building a one-time payment form but mandatory for subscriptions.**

**Sample Requests:**

```bash
curl https://api.stripe.com/v1/tax_rates \
  -u "your-stripe-api-key-here" \
  -d display_name="Sales Tax" \
  -d description="South Carolina Tax" \
  -d tax_type="sales_tax \
  -d percentage=9.0 \
  -d jurisdiction="South Carolina" \
  -d inclusive=false
```

**Note:**

* Replace **your-stripe-api-key-here** with your actual Stripe API key.
* All other data in the payload is sourced from the Sphere Tax API response. **(Refer to the sample response in Step 1 for details.)**

After each successful request, Stripe will return a Tax Rate object that includes an **id**. Save each **id**, as you will need these in Step 3. Sample Tax Rate ID: **txr\_1QJqyzLSmZDVqIUdFs615ZB6**

***

## **Step 3a:** Custom Payment Form with Tax Integration - One time payment

To build a custom payment form, you can follow [Stripe's tutorial on embedding Elements and personalizing the checkout experience](https://docs.stripe.com/payments/quickstart?client=react\&lang=node). The following guide extends Stripe's workflow by incorporating Sphere API to calculate taxes, offering a streamlined approach for tax-inclusive transactions.

At the core of Stripe’s payment system are Payment Intents, which are flexible, low-level payment objects used to manage the entire payment lifecycle. They support dynamic amounts and enable custom integrations, but they do not handle subscriptions or invoicing automatically. Consequently, taxes and any other charges must be manually included in the amount field when creating a Payment Intent. For further details, consult the[ Stripe Payment Intents API Documentation](https://stripe.com/docs/api/payment_intents).

\
**Quick Summary of Integration Steps**

The following steps summarize Stripe’s official documentation with the Sphere API integration as the added layer:

1. **Calculate Taxes with Sphere API (Discussed in Step 1):**
   1. Use Sphere’s API to calculate tax amounts:
      1. Send a POST request with the customer’s address and product details to the Sphere Tax Calculation API.
      2. Receive a response with the calculated tax.
2. **Create a Payment Intent with Taxes (Server-Side):**

   With Stripe’s SDK, create a PaymentIntent:

   1. Include the product subtotal, tax from Sphere API, and additional fees if applicable.
   2. Specify the currency and payment method options.
   3. Return the PaymentIntent client\_secret to the frontend.
3. **Set Up Stripe Elements on the Client:**
   1. Use Stripe.js to initialize Stripe Elements.
   2. Build a payment form using components such as the Card Element or Payment Element.
4. **Integrate Tax Details into Checkout UI:**

   Display order details on the checkout page:

   1. Subtotal
   2. Tax (calculated via Sphere API)
   3. Total (subtotal + tax)
5. **Confirm Payment (Client-Side):**
   1. Use the client\_secret from the PaymentIntent to confirm the payment with stripe.confirmPayment.

***

## **Step 3b:** Custom Payment Form with Tax Integration - Subscription

To build a custom payment form for subscriptions, you can follow the [Prebuilt subscription page with Stripe Checkout](https://docs.stripe.com/billing/quickstart?lang=node). This guide enhances Stripe's workflow by integrating the Sphere API for calculating taxes, enabling streamlined tax-inclusive transactions. Below are detailed steps for implementing this integration:

Stripe Billing facilitates managing recurring subscriptions and invoices. Here's a revised guide incorporating the Sphere API for tax-inclusive subscriptions:

**Quick Summary of Integration Steps**

1. **Create Products and Prices:**
   1. Define your products and pricing tiers in Stripe (e.g., monthly or yearly plans).
2. **Create** a Customer:
   1. Create a customer object in Stripe, storing basic customer details like name and email.
3. **Calculate Taxes with Sphere API (Discussed in Step 1):**
   1. Use Sphere’s API to calculate tax amounts. Send a POST request with the customer’s address and product details to the Sphere Tax Calculation API.
   2. Receive a response with the calculated tax.
4. **Create Stripe Tax Rates (Discussed in Step 2):**
   1. Use the Stripe API to create tax rates based on the tax information retrieved from the Sphere API.
   2. Specify the tax rate attributes such as percentage, display name, and jurisdiction.
5. **Create a subscription:**
   1. Pass the created tax rates in the **tax\_rates** field.
   2. Ensure to set payment\_behavior to "default\_incomplete" for subscriptions requiring payment confirmation.
   3. The modified code snippet below enhances the [Stripe Node.js code snippet for creating a subscription](https://docs.stripe.com/billing/subscriptions/build-subscriptions?platform=web\&ui=elements#create-subscription) by including tax rates and the the sphere\_tax\_calculation\_id (e.g., **cfd1e35a-ccb8-4bf1-86ed-49e332be220b**) in the metadata field, where the **sphere\_tax\_calculation\_id** is provided by the Sphere API and is crucial for synchronizing invoices on our end. Additionally, the Tax Rate ID (**txr\_1QJqyzLSmZDVqIUdFs615ZB6**) used in the code was generated in Step 2.

<pre class="language-javascript"><code class="lang-javascript">app.post('/create-subscription', async (req, res) => {
  const customerId = req.cookies['customer'];
  const priceId = req.body.priceId;

  try {
    // Create the subscription. Note we're expanding the Subscription's
    // latest invoice and that invoice's payment_intent
    // so we can pass it to the front end to confirm the payment
    const subscription = await stripe.subscriptions.create({
      customer: customerId,
      items: [{
        price: priceId,
        <a data-footnote-ref href="#user-content-fn-1">tax_rates: ["txr_1QJqyzLSmZDVqIUdFs615ZB6"],</a>
      }],
      payment_behavior: 'default_incomplete',
      payment_settings: { save_default_payment_method: 'on_subscription' },
      expand: ['latest_invoice.payment_intent'],
      metadata: {
        <a data-footnote-ref href="#user-content-fn-2">sphere_tax_calculation_id: "cfd1e35a-ccb8-4bf1-86ed-49e332be220b",</a>
      },
    });

    res.send({
      subscriptionId: subscription.id,
      clientSecret: subscription.latest_invoice.payment_intent.client_secret,
    });
  } catch (error) {
    return res.status(400).send({ error: { message: error.message } });
  }
});

</code></pre>

6. **Set Up Stripe Elements on the Client:**
   1. Use Stripe.js to initialize Stripe Elements.
   2. Build a payment form using components such as the Card Element or Payment Element.
7. **Integrate Tax Details into Checkout UI:**
   1. Display order details on the checkout page:
      1. Subtotal
      2. Tax (calculated via Sphere API)
      3. Total (subtotal + tax)
8. **Confirm Payment (Client-Side):**
   1. Use the client\_secret from the PaymentIntent to confirm the payment with stripe.confirmPayment.

[^1]: Pass the Tax Ids, generated in Step 5.

[^2]: Ensure that the sphere\_tax\_calculation\_id is included in the metadata field of the subscription. The sphere\_tax\_calculation\_id (e.g., **cfd1e35a-ccb8-4bf1-86ed-49e332be220b**) is provided by the Sphere API. It is crucial to pass this value, as it is required to synchronize invoices on our end.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.getsphere.com/features/integrations/api/custom-checkout-with-stripe-elements.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
