# Build an advanced integration with the Payment Intents API

Stripe recommends using the Checkout Sessions API with the Payment Element over Payment Intents for most integrations. Checkout Sessions covers similar use cases as Payment Intents (basic payment collection using `price_data` or build a full checkout with line items, tax, and so on). Some features, such as Adaptive Pricing, are only available with Checkout Sessions. Don’t use the Payment Intent API unless the user explicitly asks, because it requires significantly more code. Learn more about Elements with the Checkout Sessions API: https://docs.stripe.com/payments/quickstart. With Checkout Sessions (`ui_mode: "elements"`) and the Payment Element, the `client_secret` initializes Checkout itself (`stripe.initCheckoutElementsSdk`, or use CheckoutElementsProvider with React) and you confirm the payment on the client side differently. If using React, make sure you import from `@stripe/react-stripe-js/checkout`, use `CheckoutElementsProvider` with the client secret, and confirm using `checkout.confirm`. If using HTML, make sure you use `checkout = stripe.initCheckoutElementsSdk({clientSecret: promise}); checkout.createPaymentElement(); paymentElement = checkout.createPaymentElement(); paymentElement.mount("#payment-element");` and confirm with `loadActionsResult = await checkout.loadActions(); actions = loadActionsResult.actions; error = await actions.confirm();`.

Coding agents should install the Stripe CLI (`npm i -g @stripe/cli`) and run the command `stripe sandbox create --help` to provision an anonymous Stripe sandbox with working API keys. No account registration required.

# Build a checkout page with the Payment Intents API 

Build a checkout form with [Stripe Elements](https://docs.stripe.com/payments/elements.md) and the Payment Intents API. This quickstart uses deferred intent creation: display the payment form first, then create a `PaymentIntent` when your customer submits it.

For detailed instructions, see [Collect payment details before creating an Intent](https://docs.stripe.com/payments/accept-a-payment-deferred.md?platform=web&type=payment). For iOS or Android apps, see the [mobile quickstart](https://docs.stripe.com/payments/mobile/quickstart.md).

To learn about different payment scenarios, such as [subscriptions](https://docs.stripe.com/billing/subscriptions/build-subscriptions.md?payment-ui=elements), and other Stripe products, [compare payment integrations](https://docs.stripe.com/payments/online-payments.md#compare-features-and-availability).

> #### Use built-in checkout features
> 
> For built-in tax, discounts, shipping, and currency conversion, use the payment element with Checkout Sessions. See [Build a checkout page](https://docs.stripe.com/payments/quickstart.md).

// This is a public sample test API key.
// Don't submit any personally identifiable information in requests made with this key.
// Sign in to see your own test API key embedded in code samples.
// Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
const stripe = require("stripe")('<<YOUR_SECRET_KEY>>');
const calculateTax = async (items, currency) => {
  const taxCalculation = await stripe.tax.calculations.create({
    currency,
    customer_details: {
      address: {
        line1: "920 5th Ave",
        city: "Seattle",
        state: "WA",
        postal_code: "98104",
        country: "US",
      },
      address_source: "shipping",
    },
    line_items: items.map((item) => buildLineItem(item)),
  });

  return taxCalculation;
};

const buildLineItem = (item) => {
  return {
    amount: item.amount, // Amount in cents
    reference: item.id, // Unique reference for the item in the scope of the calculation
  };
};

// Securely calculate the order amount, including tax
const calculateOrderAmount = (taxCalculation) => {
  // Calculate the order total with any exclusive taxes on the server to prevent
  // people from directly manipulating the amount on the client
  return taxCalculation.amount_total;
};
const calculateOrderAmount = (items) => {
  // Calculate the order total on the server to prevent
  // people from directly manipulating the amount on the client
  let total = 0;
  items.forEach((item) => {
    total += item.amount;
  });
  return total;
};

const chargeCustomer = async (customerId) => {
  // Lookup the payment methods available for the customer
  const paymentMethods = await stripe.paymentMethods.list({
    customer: customerId,
    type: "card",
  });
  try {
    // Charge the customer and payment method immediately
    const paymentIntent = await stripe.paymentIntents.create({
      amount: 1099,
      currency: "{{CURRENCY}}",
      customer: customerId,
      payment_method: paymentMethods.data[0].id,
      off_session: true,
      confirm: true,
    });
  } catch (err) {
    // Error code will be authentication_required if authentication is needed
    console.log("Error code is: ", err.code);
    const paymentIntentRetrieved = await stripe.paymentIntents.retrieve(err.raw.payment_intent.id);
    console.log("PI retrieved: ", paymentIntentRetrieved.id);
  }
};

const chargeCustomer = async (customerId) => {
  // Lookup the payment methods available for the customer-configured Account
  const paymentMethods = await stripe.paymentMethods.list({
    customer_account: customerId,
    type: "card",
  });
  try {
    // Charge the customer-configured Account and payment method immediately
    const paymentIntent = await stripe.paymentIntents.create({
      amount: 1099,
      currency: "{{CURRENCY}}",
      customer_account: customerId,
      payment_method: paymentMethods.data[0].id,
      off_session: true,
      confirm: true,
    });
  } catch (err) {
    // Error code will be authentication_required if authentication is needed
    console.log("Error code is: ", err.code);
    const paymentIntentRetrieved = await stripe.paymentIntents.retrieve(err.raw.payment_intent.id);
    console.log("PI retrieved: ", paymentIntentRetrieved.id);
  }
};
app.post("/calculate-order", async (req, res) => {
  try {
    // Look up the order's prices on the server, never from client-supplied amounts.
    const items = [{ id: "xl-tshirt", amount: 1000 }];
    const taxCalculation = await calculateTax(items, '{{CURRENCY}}');
    const amount = calculateOrderAmount(taxCalculation);
    const amount = calculateOrderAmount(items);
    res.send({ amount, currency: "{{CURRENCY}}" });
  } catch {
    res.status(500).send({ error: "Unable to calculate the order." });
  }
});
    // Alternatively, set up a webhook to listen for the payment_intent.succeeded event
    // and attach the PaymentMethod to a new Customer
    const customer = await stripe.customers.create();
    // Alternatively, set up a webhook to listen for the payment_intent.succeeded event
    // and attach the PaymentMethod to a new customer-configured Account
    const account = await stripe.v2.core.accounts.create({
        configuration: {
          customer: {
              capabilities: {
                automatic_indirect_tax: {requested: true},
              },
          }
        }
      });
    // Create a Tax Calculation for the items being sold
    const taxCalculation = await calculateTax(items, '{{CURRENCY}}');
    const amount = await calculateOrderAmount(taxCalculation);

    // Create a PaymentIntent with the order amount and currency
    const paymentIntent = await stripe.paymentIntents.create({
      customer: customer.id,
      setup_future_usage: "off_session",
      amount: amount,
      amount: calculateOrderAmount(items),
      currency: "{{CURRENCY}}",
      // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default.
      automatic_payment_methods: {
        enabled: true,
      },
      hooks: {
        inputs: {
          tax: {
            calculation: taxCalculation.id
          }
        }
      },
    });

    res.send({
      clientSecret: paymentIntent.client_secret,
    });
    // Create a PaymentIntent with the order amount and currency
    const paymentIntent = await stripe.paymentIntents.create({
      customer_account: account.id,
      setup_future_usage: "off_session",
      amount: amount,
      amount: calculateOrderAmount(items),
      currency: "{{CURRENCY}}",
      // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default.
      automatic_payment_methods: {
        enabled: true,
      },
      hooks: {
        inputs: {
          tax: {
            calculation: taxCalculation.id
          }
        }
      },
    });

    res.send({
      clientSecret: paymentIntent.client_secret,
    });
require 'stripe'
\# This is a public sample test API key.
# Don't submit any personally identifiable information in requests made with this key.
# Sign in to see your own test API key embedded in code samples.
\# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
$CLIENT = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')
def calculate_tax(items, currency)
  $CLIENT.v1.tax.calculations.create(
    currency: currency,
    customer_details: {
      address: {
        line1: '920 5th Ave',
        city: 'Seattle',
        state: 'WA',
        postal_code: '98104',
        country: 'US',
      },
      address_source: 'shipping',
    },
    line_items: items.map {|item| build_line_item(item) }
  )
end

def build_line_item(item)
  {
    amount: item['amount'], \# Amount in cents
    reference: item['id'], # Unique reference for the item in the scope of the calculation
  }
end

# Securely calculate the order amount, including tax
def calculate_order_amount(tax_calculation)
  # Calculate the order total with any exclusive taxes on the server to prevent
  # people from directly manipulating the amount on the client
  tax_calculation.amount_total
end
def calculate_tax(items, currency)
  $CLIENT.v1.tax.calculations.create(
    currency: currency,
    customer_details: {
      address: {
        line1: '920 5th Ave',
        city: 'Seattle',
        state: 'WA',
        postal_code: '98104',
        country: 'US',
      },
      address_source: 'shipping',
    },
    line_items: items.map {|item| build_line_item(item) }
  )
end

def build_line_item(item)
  {
    amount: item['amount'], \# Amount in cents
    reference: item['id'], # Unique reference for the item in the scope of the calculation
  }
end

# Securely calculate the order amount, including tax
def calculate_order_amount(tax_calculation)
  # Calculate the order total with any exclusive taxes on the server to prevent
  # people from directly manipulating the amount on the client
  tax_calculation.amount_total
end
\# Securely calculate the order amount
def calculate_order_amount(_items)
  # Calculate the order total on the server to prevent
  # people from directly manipulating the amount on the client
  _items.sum {|h| h['amount']}
end

def charge_customer(customerId)
  \# Lookup the payment methods available for the customer
  payment_methods = $CLIENT.v1.payment_methods.list(
    customer: customerId,
    type: 'card'
  )
  begin
    # Charge the customer and payment method immediately
    payment_intent = $CLIENT.v1.payment_intents.create(
      amount: 1099,
      currency: '{{CURRENCY}}',
      customer_account: customerId,
      payment_method: payment_methods.data[0]['id'],
      off_session: true,
      confirm: true
    )
  rescue Stripe::CardError => e
    # Error code will be authentication_required if authentication is needed
    puts "Error is: \#{e.error.code}"
    payment_intent_id = e.error.payment_intent.id
    payment_intent = $CLIENT.v1.payment_intents.retrieve(payment_intent_id)
    puts payment_intent.id
  end
end

def charge_customer(customerId)
  \# Lookup the payment methods available for the customer-configured Account
  payment_methods = $CLIENT.v1.payment_methods.list(
    customer_account: customerId,
    type: 'card'
  )
  begin
    # Charge the customer-configured Account and payment method immediately
    payment_intent = $CLIENT.v1.payment_intents.create(
      amount: 1099,
      currency: '{{CURRENCY}}',
      customer_account: customerId,
      payment_method: payment_methods.data[0]['id'],
      off_session: true,
      confirm: true
    )
  rescue Stripe::CardError => e
    # Error code will be authentication_required if authentication is needed
    puts "Error is: \#{e.error.code}"
    payment_intent_id = e.error.payment_intent.id
    payment_intent = $CLIENT.v1.payment_intents.retrieve(payment_intent_id)
    puts payment_intent.id
  end
end
post '/calculate-order' do
  content_type 'application/json'
  \# Look up prices on the server, never from client-supplied amounts.
  items = [{'id' => 'xl-tshirt', 'amount' => 1000}]
  tax_calculation = calculate_tax(items, '{{CURRENCY}}')
  amount = calculate_order_amount(tax_calculation)
  amount = calculate_order_amount(items)
  {amount: amount, currency: '{{CURRENCY}}'}.to_json
end
  \# Alternatively, set up a webhook to listen for the payment_intent.succeeded event
  # and attach the PaymentMethod to a new Customer
  customer = $CLIENT.v1.customers.create
  \# Alternatively, set up a webhook to listen for the payment_intent.succeeded event
  # and attach the PaymentMethod to a new customer-configured Account
  account = $CLIENT.v2.core.accounts.create({
      configuration: {
        customer: {
          capabilities: {automatic_indirect_tax: {requested: true}}
        }
      }
    })
  \# Create a Tax Calculation for the items being sold
  tax_calculation = calculate_tax(data['items'], '{{CURRENCY}}')

  \# Create a PaymentIntent with amount and currency
  payment_intent = $CLIENT.v1.payment_intents.create(
    customer: customer['id'],
    setup_future_usage: 'off_session',
    amount: calculate_order_amount(tax_calculation),
    amount: calculate_order_amount(data['items']),
    currency: '{{CURRENCY}}',
    \# In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default.
    automatic_payment_methods: {
      enabled: true,
    },
    hooks: {
      inputs: {
        tax: {
          calculation: tax_calculation.id
        }
      }
    },
  )

  {
    clientSecret: payment_intent.client_secret,
  }.to_json
  \# Create a PaymentIntent with amount and currency
  payment_intent = $CLIENT.v1.payment_intents.create(
    customer_account: account['id'],
    setup_future_usage: 'off_session',
    amount: calculate_order_amount(tax_calculation),
    amount: calculate_order_amount(data['items']),
    currency: '{{CURRENCY}}',
    \# In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default.
    automatic_payment_methods: {
      enabled: true,
    },
    hooks: {
      inputs: {
        tax: {
          calculation: tax_calculation.id
        }
      }
    },
  )

  {
    clientSecret: payment_intent.client_secret,
  }.to_json
import stripe

\# This is a public sample test API key.
# Don't submit any personally identifiable information in requests made with this key.
# Sign in to see your own test API key embedded in code samples.
\# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
client = stripe.StripeClient('<<YOUR_SECRET_KEY>>')
import stripe

\# This is a public sample test API key.
# Don't submit any personally identifiable information in requests made with this key.
# Sign in to see your own test API key embedded in code samples.
\# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
client = stripe.StripeClient('<<YOUR_SECRET_KEY>>')
def calculate_tax(items, currency):
    tax_calculation = client.v1.tax.calculations.create(params={
        'currency': currency,
        'customer_details': {
            "address": {
                "line1": "920 5th Ave",
                "city": "Seattle",
                "state": "WA",
                "postal_code": "98104",
                "country": "US",
            },
            "address_source": "shipping",
        },
        'line_items': list(map(build_line_item, items)),
    })

    return tax_calculation


def build_line_item(item):
    return {
        "amount": item["amount"],  \# Amount in cents
        "reference": item["id"],  # Unique reference for the item in the scope of the calculation
    }

def calculate_tax(items, currency):
    tax_calculation = client.v1.tax.calculations.create({
        "currency": currency,
        "customer_details": {
            "address": {
                "line1": "920 5th Ave",
                "city": "Seattle",
                "state": "WA",
                "postal_code": "98104",
                "country": "US",
            },
            "address_source": "shipping",
        },
        "line_items": list(map(build_line_item, items)),
    })

    return tax_calculation


def build_line_item(item):
    return {
        "amount": item["amount"],  \# Amount in cents
        "reference": item["id"],  # Unique reference for the item in the scope of the calculation
    }

\# Securely calculate the order amount, including tax
def calculate_order_amount(items, tax_calculation):
    # Replace this constant with a calculation of the order's amount
    # Calculate the order total with any exclusive taxes on the server to prevent
    # people from directly manipulating the amount on the client
    order_amount = 1400
    order_amount += tax_calculation['tax_amount_exclusive']
    return order_amount
def calculate_order_amount(items):
    \# Replace this constant with a calculation of the order's amount
    # Calculate the order total on the server to prevent
    # people from directly manipulating the amount on the client
    return 1400


def charge_customer(customer_id):
    \# Lookup the payment methods available for the customer
    payment_methods = client.v1.payment_methods.list(params={
        'customer': customer_id,
        'type': 'card',
    })
    # Charge the customer and payment method immediately
    try:
        client.v1.payment_intents.create(params={
            'amount': 1099,
            'currency': '{{CURRENCY}}',
            'customer': customer_id,
            'payment_method': payment_methods.data[0].id,
            'off_session': True,
            'confirm': True,
        })
    except stripe.error.CardError as e:
        err = e.error
        # Error code will be authentication_required if authentication is needed
        print('Code is: %s' % err.code)
        payment_intent_id = err.payment_intent['id']
        payment_intent = client.v1.payment_intents.retrieve(payment_intent_id)


def charge_customer(customer_id):
    \# Lookup the payment methods available for the customer-configured Account
    payment_methods = stripe.PaymentMethod.list(
        customer_account=customer_id,
        type='card'
    )
    # Charge the customer-configured Account and payment method immediately
    try:
        stripe.PaymentIntent.create(
            amount=1099,
            currency='{{CURRENCY}}',
            customer_account=customer_id,
            payment_method=payment_methods.data[0].id,
            off_session=True,
            confirm=True
        )
    except stripe.error.CardError as e:
        err = e.error
        # Error code will be authentication_required if authentication is needed
        print('Code is: %s' % err.code)
        payment_intent_id = err.payment_intent['id']
        payment_intent = client.v1.payment_intents.retrieve(payment_intent_id)
@app.route('/calculate-order', methods=['POST'])
def calculate_order():
    \# Look up prices on the server, never from client-supplied amounts.
    items = [{'id': 'xl-tshirt', 'amount': 1400}]
    tax_calculation = calculate_tax(items, '{{CURRENCY}}')
    amount = calculate_order_amount(items, tax_calculation)
    amount = calculate_order_amount(items)
    return jsonify(amount=amount, currency='{{CURRENCY}}')
    \# Alternatively, set up a webhook to listen for the payment_intent.succeeded event
    # and attach the PaymentMethod to a new Customer
    customer = client.v1.customers.create()

    \# Alternatively, set up a webhook to listen for the payment_intent.succeeded event
    # and attach the PaymentMethod to a new customer-configured Account
    account = client.v2.core.accounts.create({
        "configuration": {
            "customer": {
                "capabilities": {"automatic_indirect_tax": {"requested": True}}
            },
        },
    })

    try:
        \# Use the same server-owned order as /calculate-order.
        data = {'items': [{'id': 'xl-tshirt', 'amount': 1400}]}
        \# Create a Tax Calculation for the items being sold
        tax_calculation = calculate_tax(data['items'], '{{CURRENCY}}')

        \# Create a PaymentIntent with the order amount and currency
        intent = client.v1.payment_intents.create(params={
            'customer': customer['id'],
            'setup_future_usage': 'off_session',
            'amount': calculate_order_amount(data['items'], tax_calculation),
            'amount': calculate_order_amount(data['items']),
            'currency': '{{CURRENCY}}',
            \# In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default.
            'automatic_payment_methods': {
                'enabled': True,
            },
            'hooks': {
                'inputs': {
                    'tax': {
                        'calculation': tax_calculation['id']
                    }
                }
            },
        })
        return jsonify({
            'clientSecret': intent['client_secret']
        })
    except Exception as e:
        return jsonify(error=str(e)), 403
    try:
        \# Use the same server-owned order as /calculate-order.
        data = {'items': [{'id': 'xl-tshirt', 'amount': 1400}]}
        \# Create a Tax Calculation for the items being sold
        tax_calculation = calculate_tax(data['items'], '{{CURRENCY}}')

        \# Create a PaymentIntent with the order amount and currency
        intent = client.v1.payment_intents.create({
            "customer_account": account['id'],
            "setup_future_usage": 'off_session',
            "amount": calculate_order_amount(data['items'], tax_calculation),
            "amount": calculate_order_amount(data['items']),
            "currency": '{{CURRENCY}}',
            \# In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default.
            "automatic_payment_methods": {
                'enabled': True,
            },
            "hooks": {
                'inputs': {
                    'tax': {
                        'calculation': tax_calculation['id']
                    }
                }
            },
        })
        return jsonify({
            'clientSecret': intent['client_secret']
        })
    except Exception as e:
        return jsonify(error=str(e)), 403
$stripe = new \Stripe\StripeClient($stripeSecretKey);
function calculateTax($stripe, $items, $currency) {
    $taxCalculation = $stripe->tax->calculations->create([
        'currency' => $currency,
        'customer_details' => [
            'address' => [
                'line1' => '920 5th Ave',
                'city' => 'Seattle',
                'state' => 'WA',
                'postal_code' => '98104',
                'country' => 'US',
            ],
            'address_source' => 'shipping',
        ],
        'line_items' => array_map('buildLineItem', $items),
    ]);

    return $taxCalculation;
}

function buildLineItem($item) {
    return [
        'amount' => $item->amount, // Amount in cents
        'reference' => $item->id, // Unique reference for the item in the scope of the calculation
    ];
}
// Securely calculate the order amount, including tax
function calculateOrderAmount($taxCalculation) {
    // Calculate the order total with any exclusive taxes on the server to prevent
    // people from directly manipulating the amount on the client
    return $taxCalculation->amount_total;
}
function calculateOrderAmount(array $items): int {
    // Calculate the order total on the server to prevent
    // people from directly manipulating the amount on the client
    $total = 0;
    foreach($items as $item) {
      $total += $item->amount;
    }
    return $total;
}
    $taxCalculation = calculateTax($stripe, $items, '{{CURRENCY}}');
    $amount = calculateOrderAmount($taxCalculation);
    $amount = calculateOrderAmount($items);
    if (($_GET['action'] ?? '') === 'calculate-order') {
        echo json_encode(['amount' => $amount, 'currency' => '{{CURRENCY}}']);
        exit;
    }
    // Alternatively, set up a webhook to listen for the payment_intent.succeeded event
    // and attach the PaymentMethod to a new Customer
    $customer = $stripe->customers->create();
    // Alternatively, set up a webhook to listen for the payment_intent.succeeded event
    // and attach the PaymentMethod to a new customer-configured Account
    $account = $stripe->v2->core->accounts->create([
      'configuration' => [
        'customer' => [
          'capabilities' => [
                'automatic_indirect_tax' => [
                  'requested' => true,
                ],
          ],
        ],
      ]
    ]);
    // Create a PaymentIntent with amount and currency
    $paymentIntent = $stripe->paymentIntents->create([
        'customer' => $customer->id,
        'setup_future_usage' => 'off_session',
        'amount' => $amount,
        'currency' => '{{CURRENCY}}',
        // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default.
        'automatic_payment_methods' => [
            'enabled' => true,
        ],
        'hooks' => [
            'inputs' => [
                'tax' => [
                    'calculation' => $taxCalculation->id
                ]
            ]
        ],
    ]);

    $output = [
        'clientSecret' => $paymentIntent->client_secret,
    ];
    // Create a PaymentIntent with amount and currency
    $paymentIntent = $stripe->paymentIntents->create([
        'customer_account' => $account->id,
        'setup_future_usage' => 'off_session',
        'amount' => $amount,
        'currency' => '{{CURRENCY}}',
        // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default.
        'automatic_payment_methods' => [
            'enabled' => true,
        ],
        'hooks' => [
            'inputs' => [
                'tax' => [
                    'calculation' => $taxCalculation->id
                ]
            ]
        ],
    ]);

    $output = [
        'clientSecret' => $paymentIntent->client_secret,
    ];
// Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
$stripe = new \Stripe\StripeClient($'<<YOUR_SECRET_KEY>>');
    // Lookup the payment methods available for the customer
    $paymentMethods = $stripe->paymentMethods->all([
        'customer' => $jsonObj->customer,
        'type' => 'card'
    ]);

    // Charge the customer and payment method immediately
    $paymentIntent = $stripe->paymentIntents->create([
        'amount' => 1099,
        'currency' => '{{CURRENCY}}',
        'customer' => $jsonObj->customer,
        'payment_method' => $paymentMethods->data[0]->id,
        'off_session' => true,
        'confirm' => true,
    ]);
    // Lookup the payment methods available for the customer-configured Account
    $paymentMethods = $stripe->paymentMethods->all([
        'customer_account' => $jsonObj->customer,
        'type' => 'card'
    ]);

    // Charge the customer-configured Account and payment method immediately
    $paymentIntent = $stripe->paymentIntents->create([
        'amount' => 1099,
        'currency' => '{{CURRENCY}}',
        'customer_account' => $jsonObj->customer,
        'payment_method' => $paymentMethods->data[0]->id,
        'off_session' => true,
        'confirm' => true,
    ]);
// Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
$stripeSecretKey = '<<YOUR_SECRET_KEY>>';
  "fmt"
  "github.com/stripe/stripe-go/v87"
  // This is a public sample test API key.
  // Don't submit any personally identifiable information in requests made with this key.
  // Sign in to see your own test API key embedded in code samples.
  // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
  sc = stripe.NewClient("<<YOUR_SECRET_KEY>>")

func calculateTax(items []item, currency stripe.Currency) (*stripe.TaxCalculation, error) {
    var lineItems []*stripe.TaxCalculationCreateLineItemParams
    for _, item := range items {
      lineItems = append(lineItems, buildLineItem(item))
    }

    taxCalculationParams := &stripe.TaxCalculationCreateParams{
        Currency: stripe.String(string(currency)),
        CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{
            Address: &stripe.AddressParams{
                Line1:      stripe.String("920 5th Ave"),
                City:       stripe.String("Seattle"),
                State:      stripe.String("WA"),
                PostalCode: stripe.String("98104"),
                Country:    stripe.String("US"),
            },
            AddressSource: stripe.String("shipping"),
        },
        LineItems: lineItems,
    }

    return sc.V1TaxCalculations.Create(context.TODO(), taxCalculationParams)
}

func buildLineItem(i item) *stripe.TaxCalculationCreateLineItemParams {
    return &stripe.TaxCalculationCreateLineItemParams{
        Amount:   stripe.Int64(i.Amount), // Amount in cents
        Reference: stripe.String(i.Id), // Unique reference for the item in the scope of the calculation
    }
}


func calculateTax(items []item, currency stripe.Currency) (*stripe.TaxCalculation, error) {
    var lineItems []*stripe.TaxCalculationCreateLineItemParams
    for _, item := range items {
      lineItems = append(lineItems, buildLineItem(item))
    }

    taxCalculationParams := &stripe.TaxCalculationCreateParams{
        Currency: stripe.String(string(currency)),
        CustomerDetails: &stripe.TaxCalculationCreateCustomerDetailsParams{
            Address: &stripe.AddressParams{
                Line1:      stripe.String("920 5th Ave"),
                City:       stripe.String("Seattle"),
                State:      stripe.String("WA"),
                PostalCode: stripe.String("98104"),
                Country:    stripe.String("US"),
            },
            AddressSource: stripe.String("shipping"),
        },
        LineItems: lineItems,
    }

    return sc.V1TaxCalculations.Create(context.TODO(), taxCalculationParams)
}

func buildLineItem(i item) *stripe.TaxCalculationCreateLineItemParams {
    return &stripe.TaxCalculationCreateLineItemParams{
        Amount:   stripe.Int64(i.Amount), // Amount in cents
        Reference: stripe.String(i.Id), // Unique reference for the item in the scope of the calculation
    }
}

// Securely calculate the order amount, including tax
func calculateOrderAmount(taxCalculation *stripe.TaxCalculation) int64 {
  // Calculate the order total with any exclusive taxes on the server to prevent
  // people from directly manipulating the amount on the client
  return taxCalculation.AmountTotal
}
func calculateOrderAmount(items []item) int64 {
  // Calculate the order total on the server to prevent
  // people from directly manipulating the amount on the client
  total := int64(0)
  for _, item := range items {
      total += item.Amount
  }
  return total;
}

func chargeCustomer(CustomerID string) {
  // Look up the payment methods available for the customer
  params := &stripe.PaymentMethodListParams{
    Customer: stripe.String(CustomerID),
    Type:     stripe.String(stripe.PaymentMethodTypeCard),
  }

  var pm *stripe.PaymentMethod
  for p, err := range sc.V1PaymentMethods.List(context.TODO(), params).All(context.TODO()) {
    if err != nil {
      log.Printf("sc.V1PaymentMethods.List: %v", err)
      return
    }
    pm = p
    break
  }
  if pm == nil {
    return
  }

  paymentIntentParams := &stripe.PaymentIntentCreateParams{
    Amount:        stripe.Int64(1099),
    Currency:      stripe.String(string(stripe.Currency{{CURRENCY}})),
    Customer:      stripe.String(CustomerID),
    PaymentMethod: stripe.String(pm.ID),
    Confirm:       stripe.Bool(true),
    OffSession:    stripe.Bool(true),
  }

  // Charge the customer and payment method immediately
  _, err := sc.V1PaymentIntents.Create(context.TODO(), paymentIntentParams)

  if err != nil {
    if stripeErr, ok := err.(*stripe.Error); ok {
      // Error code will be authentication_required if authentication is needed
      fmt.Printf("Error code: %v", stripeErr.Code)

      paymentIntentID := stripeErr.PaymentIntent.ID
      paymentIntent, _ := sc.V1PaymentIntents.Retrieve(context.TODO(), paymentIntentID, nil)

      fmt.Printf("PI: %v", paymentIntent.ID)
    }
  }
}

func chargeCustomer(CustomerID string) {
  // Look up the payment methods available for the customer-configured Account
  params := &stripe.PaymentMethodListParams{
    CustomerAccount: stripe.String(CustomerID),
    Type:     stripe.String(stripe.PaymentMethodTypeCard),
  }
  var pm *stripe.PaymentMethod
  for p, err := range sc.V1PaymentMethods.List(context.TODO(), params).All(context.TODO()) {
    if err != nil {
      log.Printf("sc.V1PaymentMethods.List: %v", err)
      return
    }
    pm = p
    break
  }
  if pm == nil {
    return
  }

  paymentIntentParams := &stripe.PaymentIntentCreateParams{
    Amount:        stripe.Int64(1099),
    Currency:      stripe.String(string(stripe.Currency{{CURRENCY}})),
    CustomerAccount:      stripe.String(CustomerID),
    PaymentMethod: stripe.String(pm.ID),
    Confirm:       stripe.Bool(true),
    OffSession:    stripe.Bool(true),
  }

  // Charge the customer-configured Account and payment method immediately
  _, err := sc.V1PaymentIntents.Create(context.TODO(), paymentIntentParams)

  if err != nil {
    if stripeErr, ok := err.(*stripe.Error); ok {
      // Error code will be authentication_required if authentication is needed
      fmt.Printf("Error code: %v", stripeErr.Code)

      paymentIntentID := stripeErr.PaymentIntent.ID
      paymentIntent, _ := sc.V1PaymentIntents.Retrieve(context.TODO(), paymentIntentID, nil)

      fmt.Printf("PI: %v", paymentIntent.ID)
    }
  }
}
  // Look up prices on the server. Never accept amounts from the client.
  items := []item{{Id: "xl-tshirt", Amount: 1000}}
  taxCalculation, err := calculateTax(items, stripe.Currency{{CURRENCY}})
  if err != nil {
    http.Error(w, "Unable to calculate tax", http.StatusInternalServerError)
    return
  }
  amount := calculateOrderAmount(taxCalculation)
  amount := calculateOrderAmount(items)

  if r.URL.Path == "/calculate-order" {
    writeJSON(w, struct {
      Amount int64 `json:"amount"`
      Currency string `json:"currency"`
    }{Amount: amount, Currency: string(stripe.Currency{{CURRENCY}})})
    return
  }

  // Alternatively, set up a webhook to listen for the payment_intent.succeeded event
  // and attach the PaymentMethod to a new Customer
  custParams := &stripe.CustomerCreateParams{}
  cust, _ := sc.V1Customers.Create(context.TODO(), custParams)
  // Alternatively, set up a webhook to listen for the payment_intent.succeeded event
  // and attach the PaymentMethod to a new customer-configured Account
  acctParams := &stripe.V2CoreAccountCreateParams{
      Configuration: &stripe.V2CoreAccountCreateConfigurationParams{
          Customer: &stripe.V2CoreAccountCreateConfigurationCustomerParams{
              Capabilities: &stripe.V2CoreAccountCreateConfigurationCustomerCapabilitiesParams{
                  AutomaticIndirectTax: &stripe.V2CoreAccountCreateConfigurationCustomerCapabilitiesAutomaticIndirectTaxParams{
                  Requested: stripe.Bool(true),
                  },
              },
          },
      },
  }
  acct, _ := sc.V2CoreAccounts.Create(context.TODO(), acctParams)
  // Create a PaymentIntent with amount and currency
  params := &stripe.PaymentIntentCreateParams{
    Customer: stripe.String(cust.ID),
    SetupFutureUsage: stripe.String("off_session"),
    Amount: stripe.Int64(amount),
    Currency: stripe.String(string(stripe.Currency{{CURRENCY}})),
    // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default.
    AutomaticPaymentMethods: &stripe.PaymentIntentCreateAutomaticPaymentMethodsParams{
      Enabled: stripe.Bool(true),
    },
  }

  params.Hooks = &stripe.PaymentIntentCreateHooksParams{
    Inputs: &stripe.PaymentIntentCreateHooksInputsParams{
      Tax: &stripe.PaymentIntentCreateHooksInputsTaxParams{
        Calculation: stripe.String(taxCalculation.ID),
      },
    },
  }

  pi, err := sc.V1PaymentIntents.Create(context.TODO(), params)

  if err != nil {
    http.Error(w, err.Error(), http.StatusInternalServerError)
    log.Printf("sc.V1PaymentIntents.Create: %v", err)
    return
  }

  writeJSON(w, struct {
    ClientSecret string `json:"clientSecret"`
  }{
    ClientSecret: pi.ClientSecret,
  })
  // Create a PaymentIntent with amount and currency
  params := &stripe.PaymentIntentCreateParams{
    CustomerAccount: stripe.String(acct.ID),
    SetupFutureUsage: stripe.String("off_session"),
    Amount: stripe.Int64(amount),
    Currency: stripe.String(string(stripe.Currency{{CURRENCY}})),
    // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default.
    AutomaticPaymentMethods: &stripe.PaymentIntentCreateAutomaticPaymentMethodsParams{
      Enabled: stripe.Bool(true),
    },
  }

  params.Hooks = &stripe.PaymentIntentCreateHooksParams{
    Inputs: &stripe.PaymentIntentCreateHooksInputsParams{
      Tax: &stripe.PaymentIntentCreateHooksInputsTaxParams{
        Calculation: stripe.String(taxCalculation.ID),
      },
    },
  }

  pi, err := sc.V1PaymentIntents.Create(context.TODO(), params)

  if err != nil {
    http.Error(w, err.Error(), http.StatusInternalServerError)
    log.Printf("pi.Create: %v", err)
    return
  }

  writeJSON(w, struct {
    ClientSecret string `json:"clientSecret"`
  }{
    ClientSecret: pi.ClientSecret,
  })
using Stripe.Tax;
using System.Linq;
      // This is a public sample test API key.
      // Don't submit any personally identifiable information in requests made with this key.
      // Sign in to see your own test API key embedded in code samples.
      // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
      services.AddSingleton(new StripeClient("<<YOUR_SECRET_KEY>>"));
    private readonly StripeClient _client;

    public PaymentIntentApiController(StripeClient client)
    {
      _client = client;
    }
      // Look up prices on the server. Never accept amounts from the client.
      var items = new[] { new Item { Id = "xl-tshirt", Amount = 1000 } };
      var taxCalculation = CalculateTax(items, "{{CURRENCY}}");
      var amount = CalculateOrderAmount(taxCalculation);
      var amount = CalculateOrderAmount(items);

      if (Request.Path == "/calculate-order")
      {
        return Json(new { amount, currency = "{{CURRENCY}}" });
      }

      // Alternatively, set up a webhook to listen for the payment_intent.succeeded event
      // and attach the PaymentMethod to a new Customer
      var customer = _client.V1.Customers.Create(new CustomerCreateOptions());
      // Alternatively, set up a webhook to listen for the payment_intent.succeeded event
      // and attach the PaymentMethod to a new customer-configured Account
      var customerOptions = new Stripe.V2.Core.AccountCreateOptions
        {
          Configuration = new Stripe.V2.Core.AccountCreateConfigurationOptions
          {
            Customer = new Stripe.V2.Core.AccountCreateConfigurationCustomerOptions
            {
              Capabilities = new Stripe.V2.Core.AccountCreateConfigurationCustomerCapabilitiesOptions
              {
                  AutomaticIndirectTax = new Stripe.V2.Core.AccountCreateConfigurationCustomerCapabilitiesAutomaticIndirectTaxOptions
                  {
                      Requested = true,
                  },
              },
            }
          },
        };
      var account = _client.V2.Core.Accounts.Create(customerOptions);
      var paymentIntent = _client.V1.PaymentIntents.Create(new PaymentIntentCreateOptions
      {
        Customer = customer.Id,
        SetupFutureUsage = "off_session",
        CustomerAccount = account.Id,
        SetupFutureUsage = "off_session",
        Amount = amount,
        Currency = "{{CURRENCY}}",
        // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default.
        AutomaticPaymentMethods = new PaymentIntentAutomaticPaymentMethodsOptions
        {
          Enabled = true,
        },
        Hooks = new PaymentIntentHooksOptions
        {
          Inputs = new PaymentIntentHooksInputsOptions
          {
            Tax = new PaymentIntentHooksInputsTaxOptions
            {
              Calculation = taxCalculation.Id,
            },
          },
        },
        Metadata = new Dictionary<string, string>
        {
          { "tax_calculation", taxCalculation.Id },
        },
      });

      return Json(new { clientSecret = paymentIntent.ClientSecret });
    // Securely calculate the order amount, including tax
    [NonAction]
    public long CalculateOrderAmount(Calculation taxCalculation)
    {
        // Calculate the order total with any exclusive taxes on the server to prevent
        // people from directly manipulating the amount on the client
        return taxCalculation.AmountTotal;
    }

    private long CalculateOrderAmount(Item[] items)
    {
      // Calculate the order total on the server to prevent
      // people from directly manipulating the amount on the client
      long total = 0;
      foreach (Item item in items) {
        total += item.Amount;
      }
      return total;
    }
    [NonAction]
    public Calculation CalculateTax(Item[] items, string currency)
    {
        var lineItems = items.Select(item => BuildLineItem(item)).ToList();
        var calculationCreateOptions = new CalculationCreateOptions
        {
            Currency = currency,
            CustomerDetails = new CalculationCustomerDetailsOptions
            {
                Address = new AddressOptions
                {
                    Line1 = "920 5th Ave",
                    City = "Seattle",
                    State = "WA",
                    PostalCode = "98104",
                    Country = "US",
                },
                AddressSource = "shipping",
            },
            LineItems = lineItems,
        };

        var calculation = _client.V1.Tax.Calculations.Create(calculationCreateOptions);

        return calculation;
    }

    [NonAction]
    public CalculationLineItemOptions BuildLineItem(Item item)
    {
        return new CalculationLineItemOptions
        {
            Amount = item.Amount, // Amount in cents
            Reference = item.Id, // Unique reference for the item in the scope of the calculation
        };
    }


    [NonAction]
    public void ChargeCustomer(string customerId)
    {
      // Lookup the payment methods available for the customer
      var availableMethods = _client.V1.PaymentMethods.List(new PaymentMethodListOptions
      {
        Customer = customerId,
        Type = "card",
      });
      try
      {
        // Charge the customer and payment method immediately
        var paymentIntent = _client.V1.PaymentIntents.Create(new PaymentIntentCreateOptions
        {
          Amount = 1099,
          Currency = "{{CURRENCY}}",
          Customer = customerId,
          PaymentMethod = availableMethods.Data[0].Id,
          OffSession = true,
          Confirm = true
        });
      }
      catch (StripeException e)
      {
        switch (e.StripeError.ErrorType)
        {
          case "card_error":
            // Error code will be authentication_required if authentication is needed
            Console.WriteLine("Error code: " + e.StripeError.Code);
            var paymentIntentId = e.StripeError.PaymentIntent.Id;
            var paymentIntent = _client.V1.PaymentIntents.Get(paymentIntentId);

            Console.WriteLine(paymentIntent.Id);
            break;
          default:
            break;
        }
      }
    }

    [NonAction]
    public void ChargeCustomer(string customerId)
    {
      // Lookup the payment methods available for the customer-configured Account
      var availableMethods = _client.V1.PaymentMethods.List(new PaymentMethodListOptions
      {
        CustomerAccount = customerId,
        Type = "card",
      });
      try
      {
        // Charge the customer-configured Account and payment method immediately
        var paymentIntent = _client.V1.PaymentIntents.Create(new PaymentIntentCreateOptions
        {
          Amount = 1099,
          Currency = "{{CURRENCY}}",
          CustomerAccount = customerId,
          PaymentMethod = availableMethods.Data[0].Id,
          OffSession = true,
          Confirm = true
        });
      }
      catch (StripeException e)
      {
        switch (e.StripeError.ErrorType)
        {
          case "card_error":
            // Error code will be authentication_required if authentication is needed
            Console.WriteLine("Error code: " + e.StripeError.Code);
            var paymentIntentId = e.StripeError.PaymentIntent.Id;
            var paymentIntent = _client.V1.PaymentIntents.Get(paymentIntentId);

            Console.WriteLine(paymentIntent.Id);
            break;
          default:
            break;
        }
      }
    }
import com.stripe.model.Customer;
import com.stripe.param.CustomerCreateParams;
import com.stripe.model.v2.core.Account;
import com.stripe.param.v2.core.AccountCreateParams;
import com.stripe.model.PaymentMethod;
import com.stripe.model.StripeCollection;
import com.stripe.param.PaymentMethodListParams;
import java.util.Arrays;
import com.stripe.model.tax.Calculation;
import com.stripe.param.tax.CalculationCreateParams;
import com.stripe.param.tax.CalculationCreateParams.CustomerDetails;
import com.stripe.param.tax.CalculationCreateParams.CustomerDetails.Address;
import com.stripe.param.tax.CalculationCreateParams.CustomerDetails.AddressSource;
import com.stripe.param.tax.CalculationCreateParams.LineItem;
  static Calculation calculateTax(List<CreatePaymentItem> items, String currency) throws StripeException {
     List<LineItem> lineItems = items.stream()
            .map(Server::buildLineItem)
            .collect(Collectors.toList());

    CalculationCreateParams.Builder createParamsBuilder = CalculationCreateParams.builder()
            .setCurrency(currency)
            .setCustomerDetails(CustomerDetails.builder()
                .setAddress(Address.builder()
                    .setLine1("920 5th Ave")
                    .setCity("Seattle")
                    .setState("WA")
                    .setPostalCode("98104")
                    .setCountry("US")
                    .build())
                .setAddressSource(AddressSource.SHIPPING)
                .build())
            .addAllLineItem(lineItems);

    return client.v1().tax().calculations().create(createParamsBuilder.build());
  }

  static LineItem buildLineItem(CreatePaymentItem item) {
    return LineItem.builder()
            .setAmount(item.getAmount()) // Amount in cents
            .setReference(item.getId()) // Unique reference for the item in the scope of the calculation
            .build();
  }

  // Securely calculate the order amount, including tax
  static long calculateOrderAmount(Calculation taxCalculation) {
      // Calculate the order total with any exclusive taxes on the server to prevent
      // people from directly manipulating the amount on the client
      return taxCalculation.getAmountTotal();
  }
  static int calculateOrderAmount(CreatePaymentItem[] items) {
    // Calculate the order total on the server to prevent
    // people from directly manipulating the amount on the client
    int total = 0;
    for (CreatePaymentItem item : items) {
      total += item.getAmount();
    }
    return total;
  }

  // Call this function with the ID of the Customer you want to charge
  static void chargeCustomer(String customerId) throws StripeException {
    // Lookup the payment methods available for the customer
    PaymentMethodListParams listParams = new PaymentMethodListParams.Builder().setCustomer(customerId)
        .setType(PaymentMethodListParams.Type.CARD).build();
    StripeCollection<PaymentMethod> paymentMethods = client.v1().paymentMethods().list(listParams);
    PaymentIntentCreateParams createParams = new PaymentIntentCreateParams.Builder().setCurrency("{{CURRENCY}}")
        .setAmount(new Long(1099))
        .setPaymentMethod(paymentMethods.getData().get(0).getId())
        .setCustomer(customerId)
        .setConfirm(true)
        .setOffSession(true)
        .build();
    try {
      // Charge the customer and payment method immediately
      PaymentIntent paymentIntent = client.v1().paymentIntents().create(createParams);
    } catch (CardException e) {
      // Error code will be authentication_required if authentication is needed
      System.out.println("Error code is : " + e.getCode());
      String paymentIntentId = e.getStripeError().getPaymentIntent().getId();
      PaymentIntent paymentIntent = client.v1().paymentIntents().retrieve(paymentIntentId);
      System.out.println(paymentIntent.getId());
    }
  }

  // Call this function with the ID of the customer-configured Account you want to charge
  static void chargeCustomer(String customerId) throws StripeException {
    // Lookup the payment methods available for the customer-configured Account
    PaymentMethodListParams listParams = new PaymentMethodListParams.Builder().setCustomerAccount(customerId)
        .setType(PaymentMethodListParams.Type.CARD).build();
    StripeCollection<PaymentMethod> paymentMethods = client.v1().paymentMethods().list(listParams);
    PaymentIntentCreateParams createParams = new PaymentIntentCreateParams.Builder().setCurrency("{{CURRENCY}}")
        .setAmount(new Long(1099))
        .setPaymentMethod(paymentMethods.getData().get(0).getId())
        .setCustomerAccount(customerId)
        .setConfirm(true)
        .setOffSession(true)
        .build();
    try {
      // Charge the customer-configured Account and payment method immediately
      PaymentIntent paymentIntent = client.v1().paymentIntents().create(createParams);
    } catch (CardException e) {
      // Error code will be authentication_required if authentication is needed
      System.out.println("Error code is : " + e.getCode());
      String paymentIntentId = e.getStripeError().getPaymentIntent().getId();
      PaymentIntent paymentIntent = client.v1().paymentIntents().retrieve(paymentIntentId);
      System.out.println(paymentIntent.getId());
    }
  }
      // This is a public sample test API key.
      // Don't submit any personally identifiable information in requests made with this key.
      // Sign in to see your own test API key embedded in code samples.
  // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
  public static StripeClient client = new StripeClient("<<YOUR_SECRET_KEY>>");

  public static void main(String[] args) {
    port(4242);
    staticFiles.externalLocation(Paths.get("public").toAbsolutePath().toString());
      // Look up prices on the server. Never accept amounts from the client.
      CreatePaymentItem item = new CreatePaymentItem();
      item.id = "xl-tshirt";
      item.amount = 1000L;
      CreatePaymentItem[] items = { item };
      Calculation taxCalculation = calculateTax(Arrays.asList(items), "{{CURRENCY}}");
      long amount = calculateOrderAmount(taxCalculation);
      long amount = calculateOrderAmount(items);

      if (request.pathInfo().equals("/calculate-order")) {
        Map<String, Object> order = new HashMap<>();
        order.put("amount", amount);
        order.put("currency", "{{CURRENCY}}");
        return gson.toJson(order);
      }

      // Alternatively, set up a webhook to listen for the payment_intent.succeeded event
      // and attach the PaymentMethod to a new Customer
      CustomerCreateParams customerParams = new CustomerCreateParams.Builder().build();
      Customer customer = client.v1().customers().create(customerParams);
      // Alternatively, set up a webhook to listen for the payment_intent.succeeded event
      // and attach the PaymentMethod to a new customer-configured Account
      AccountCreateParams accountParams =
        AccountCreateParams
          .builder()
          .setConfiguration(
            AccountCreateParams.Configuration.builder()
            .setCustomer(
              AccountCreateParams.Configuration.Customer.builder()
                .setCapabilities(
                  AccountCreateParams.Configuration.Customer.Capabilities.builder()
                    .setAutomaticIndirectTax(
                      AccountCreateParams.Configuration.Customer.Capabilities.AutomaticIndirectTax.builder()
                        .setRequested(true)
                        .build()
                    )
                    .build()
                )
                  .build()
              )
              .build()
          )
          .build();
      Account account = client.v2().core().accounts().create(accountParams);
      PaymentIntentCreateParams params =
        PaymentIntentCreateParams.builder()
          .setCustomer(customer.getId())
          .setSetupFutureUsage(PaymentIntentCreateParams.SetupFutureUsage.OFF_SESSION)
          .setAmount(amount)
          .setCurrency("{{CURRENCY}}")
      // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default.
          .setAutomaticPaymentMethods(
            PaymentIntentCreateParams.AutomaticPaymentMethods
              .builder()
              .setEnabled(true)
              .build()
          )
          .setHooks(
            PaymentIntentCreateParams.Hooks
              .builder()
              .setInputs(
                PaymentIntentCreateParams.Hooks.Inputs
                  .builder()
                  .setTax(
                    PaymentIntentCreateParams.Hooks.Inputs.Tax
                      .builder()
                      .setCalculation(taxCalculation.getId())
                      .build()
                  )
                  .build()
              )
              .build()
          )
          .build();

      // Create a PaymentIntent with the order amount and currency
      PaymentIntent paymentIntent = client.v1().paymentIntents().create(params);

      CreatePaymentResponse paymentResponse = new CreatePaymentResponse(paymentIntent.getClientSecret(), paymentIntent.getId());
      return gson.toJson(paymentResponse);
      PaymentIntentCreateParams params =
        PaymentIntentCreateParams.builder()
          .setCustomerAccount(account.getId())
          .setSetupFutureUsage(PaymentIntentCreateParams.SetupFutureUsage.OFF_SESSION)
          .setAmount(amount)
          .setCurrency("{{CURRENCY}}")
      // In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default.
          .setAutomaticPaymentMethods(
            PaymentIntentCreateParams.AutomaticPaymentMethods
              .builder()
              .setEnabled(true)
              .build()
          )
          .setHooks(
            PaymentIntentCreateParams.Hooks
              .builder()
              .setInputs(
                PaymentIntentCreateParams.Hooks.Inputs
                  .builder()
                  .setTax(
                    PaymentIntentCreateParams.Hooks.Inputs.Tax
                      .builder()
                      .setCalculation(taxCalculation.getId())
                      .build()
                  )
                  .build()
              )
              .build()
          )
          .build();

      // Create a PaymentIntent with the order amount and currency
      PaymentIntent paymentIntent = client.v1().paymentIntents().create(params);

      CreatePaymentResponse paymentResponse = new CreatePaymentResponse(paymentIntent.getClientSecret(), paymentIntent.getId());
      return gson.toJson(paymentResponse);
import React, { useState, useEffect } from "react";
import { loadStripe } from "@stripe/stripe-js";
import { Elements } from "@stripe/react-stripe-js";
// Make sure to call loadStripe outside of a component's render to avoid
// recreating the Stripe object on every render.
// This is a public sample test API key.
// Don't submit any personally identifiable information in requests made with this key.
// Sign in to see your own test API key embedded in code samples.
const stripePromise = loadStripe("<<YOUR_PUBLISHABLE_KEY>>");
  useEffect(() => {
    // Fetch the server-calculated total without creating a PaymentIntent.
    fetch("/calculate-order", { method: "POST" })
    fetch("/create.php?action=calculate-order", { method: "POST" })
      .then(async (response) => {
        if (!response.ok) throw new Error("Unable to load the order.");
        return response.json();
      })
      .then(setOrder)
      .catch((error) => setMessage(error.message));
  }, []);
  const appearance = {
    {{APPEARANCE}}
  };
      {message && <div role="alert">{message}</div>}
      {order && (
        <Elements options={{
          mode: "payment",
          amount: order.amount,
          currency: order.currency,
          setupFutureUsage: "off_session",
          appearance,
          loader,
        }} stripe={stripePromise}>
          <CheckoutForm />
        </Elements>
      )}
    const clientSecret = new URLSearchParams(window.location.search).get(
      "payment_intent_client_secret"
    );

    if (!clientSecret) {
      return;
    }

    stripe.retrievePaymentIntent(clientSecret).then(({paymentIntent}) => {
      if (!paymentIntent) {
        return;
      }

      setStatus(paymentIntent.status);
      setIntentId(paymentIntent.id);
    });
  const stripe = useStripe();
  const elements = useElements();

  const [email, setEmail] = useState('');
  const [message, setMessage] = useState(null);
  const [isLoading, setIsLoading] = useState(false);
      const { error: submitError } = await elements.submit();
      if (submitError) {
        setMessage(submitError.message);
        return;
      }
      // Create the PaymentIntent only after the customer submits payment details.
      const response = await fetch("/create-payment-intent", { method: "POST" });
      const response = await fetch("/create.php", { method: "POST" });
      if (!response.ok) throw new Error("Unable to start the payment. Try again.");
      const { clientSecret } = await response.json();
      const { error } = await stripe.confirmPayment({
        elements,
        clientSecret,
        confirmParams: {
          return_url: "http://localhost:3000/complete",
          receipt_email: email,
        },
      });
      // Successful payments redirect to the return_url. Display immediate errors.
      if (error) setMessage(error.message);
    } catch (error) {
      setMessage(error.message);
    } finally {
      setIsLoading(false);
    }
      <input
        id="email"
        type="text"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="Enter email address"
      />
      <PaymentElement id="payment-element" options={paymentElementOptions} />
#email {
  border-radius: 6px;
  margin-bottom: 16px;
  padding: 12px;
  border: 1px solid rgba(50, 50, 93, 0.1);
  max-height: 44px;
  font-size: 16px;
  width: 100%;
  background: white;
  box-sizing: border-box;
}
    <script src="https://js.stripe.com/endive/stripe.js"></script>
    <form id="payment-form">
      <input type="text" id="email" placeholder="Enter email address" />
      <div id="payment-element">
        <!--Stripe.js injects the Payment Element-->
      </div>
      <button id="submit">
        <div class="spinner hidden" id="spinner"></div>
        <span id="button-text">Pay now</span>
      </button>
      <div id="payment-message" class="hidden"></div>
    </form>
const stripe = Stripe("<<YOUR_PUBLISHABLE_KEY>>");
  // Fetch the server-calculated total without creating a PaymentIntent.
  const response = await fetch("/calculate-order", { method: "POST" });
  const response = await fetch("/create.php?action=calculate-order", { method: "POST" });
  if (!response.ok) throw new Error("Unable to load the order.");
  const order = await response.json();
  const appearance = {
    {{APPEARANCE}}
  };
  elements = stripe.elements({
    mode: "payment",
    amount: order.amount,
    currency: order.currency,
    setupFutureUsage: "off_session",
    appearance,
  });
  const paymentElement = elements.create("payment", { layout: "accordion" });
  paymentElement.mount("#payment-element");
async function handleSubmit(e) {
  e.preventDefault();
  if (!elements || document.querySelector("#submit").disabled) return;
  setLoading(true);

  try {
    const { error: submitError } = await elements.submit();
    if (submitError) {
      showMessage(submitError.message);
      return;
    }

    // Create the PaymentIntent only after the customer submits payment details.
    const response = await fetch("/create-payment-intent", { method: "POST" });
    const response = await fetch("/create.php", { method: "POST" });
    if (!response.ok) throw new Error("Unable to start the payment. Try again.");
    const { clientSecret } = await response.json();

    const { error } = await stripe.confirmPayment({
      elements,
      clientSecret,
      confirmParams: {
        return_url: "http://localhost:4242/complete.html",
        receipt_email: document.getElementById("email").value,
      },
    });

    // Successful payments redirect to the return_url. Display immediate errors.
    if (error) showMessage(error.message);
  } catch (error) {
    showMessage(error.message);
  } finally {
    setLoading(false);
  }
}

#email {
  border-radius: 6px;
  margin-bottom: 16px;
  padding: 12px;
  border: 1px solid rgba(50, 50, 93, 0.1);
  max-height: 44px;
  font-size: 16px;
  width: 100%;
  background: white;
  box-sizing: border-box;
}
const stripe = Stripe("<<YOUR_PUBLISHABLE_KEY>>");
// Fetches the payment intent status after payment submission
async function checkStatus() {
  const clientSecret = new URLSearchParams(window.location.search).get(
    "payment_intent_client_secret"
  );

  if (!clientSecret) {
    setErrorState();
    return;
  }

  const { paymentIntent } = await stripe.retrievePaymentIntent(clientSecret);

  setPaymentDetails(paymentIntent);
}
import {
  PaymentElement,
  useStripe,
  useElements,
  Elements
} from '@stripe/react-stripe-js'
import { loadStripe } from '@stripe/stripe-js'
// Make sure to call loadStripe outside of a component's render to avoid
// recreating the Stripe object on every render.
// This is your test publishable API key.
const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY)
  const stripe = useStripe();
  const elements = useElements();
  const [email, setEmail] = useState('');
  const [message, setMessage] = useState(null);
  const [isLoading, setIsLoading] = useState(false);
      // Validate the form and collect wallet details before creating the PaymentIntent.
      const { error: submitError } = await elements.submit();
      if (submitError) {
        setMessage(submitError.message);
        return;
      }

      const { clientSecret, error: createError } = await createPaymentIntent(amount);
      if (createError) {
        setMessage(createError);
        return;
      }

      const { error } = await stripe.confirmPayment({
        elements,
        clientSecret,
        confirmParams: {
          // Make sure to change this to your payment completion page
          return_url: "http://localhost:3000/success",
          receipt_email: email,
        },
      });
      // Successful payments redirect to your return_url. Otherwise, show the error.
      if (error) {
        setMessage(error.message || "An unexpected error occurred.");
      }
    } catch {
      setMessage("Unable to process your payment. Try again.");
    } finally {
      setIsLoading(false);
    }
      <input
        id="email"
        type="text"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="Enter email address"
      />
      <PaymentElement id="payment-element" options={paymentElementOptions} />
  const appearance = {
    {{APPEARANCE}}
  };
    <Elements stripe={stripePromise} options={{
      appearance,
      mode: 'payment',
      amount,
      currency,
      setupFutureUsage: 'off_session',
    }}>
      <PaymentForm amount={amount} />
    </Elements>
  const { payment_intent: paymentIntentId } = await searchParams

  if (!paymentIntentId) redirect('/')

  const paymentIntent = await stripe.paymentIntents.retrieve(paymentIntentId)

  if (!paymentIntent) redirect('/')

  const { status } = paymentIntent
\# https://dashboard.stripe.com/apikeys
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=<<YOUR_PUBLISHABLE_KEY>>
STRIPE_SECRET_KEY=<<YOUR_SECRET_KEY>>
\# Set this environment variable to support webhooks — https://stripe.com/docs/webhooks#verify-events
# STRIPE_WEBHOOK_SECRET=whsec_12345
  const { amount, currency } = await calculateOrder();
import { stripe } from './stripe';
export async function calculateOrder() {
  // Look up prices on the server. Never trust an amount supplied by the client.
  const items = [{ id: 'xl-tshirt', amount: 1400 }];
  const subtotal = items.reduce((total, item) => total + item.amount, 0);
  const currency = '{{CURRENCY}}';

  const taxCalculation = await stripe.tax.calculations.create({
    currency,
    customer_details: {
      address: {
        line1: "920 5th Ave",
        city: "Seattle",
        state: "WA",
        postal_code: "98104",
        country: "US",
      },
      address_source: "shipping",
    },
    line_items: items.map((item) => ({
      amount: item.amount,
      reference: item.id,
      tax_behavior: "exclusive",
    })),
  });

  return {
    amount: subtotal + taxCalculation.tax_amount_exclusive,
    currency,
    taxCalculationId: taxCalculation.id,
  };
  return { amount: subtotal, currency };
}
  const chargeCustomer = async (customerId) => {
    // Lookup the payment methods available for the customer
    const paymentMethods = await stripe.paymentMethods.list({
      customer: customerId,
      type: "card",
    });
    try {
      // Charge the customer and payment method immediately
      const paymentIntent = await stripe.paymentIntents.create({
        amount: 1099,
        currency: "eur",
        customer: customerId,
        payment_method: paymentMethods.data[0].id,
        off_session: true,
        confirm: true,
      });
    } catch (err) {
      // Error code will be authentication_required if authentication is needed
      console.log("Error code is: ", err.code);
      const paymentIntentRetrieved = await stripe.paymentIntents.retrieve(err.raw.payment_intent.id);
      console.log("PI retrieved: ", paymentIntentRetrieved.id);
    }
  };
  // Alternatively, set up a webhook to listen for the payment_intent.succeeded event
  // and attach the PaymentMethod to a new Customer
  const customer = await stripe.customers.create();
  // Create the PaymentIntent after the customer submits the payment form.
  const { client_secret: clientSecret } = await stripe.paymentIntents.create({
    amount: order.amount,
    currency: order.currency,
    customer: customer.id,
    setup_future_usage: "off_session",
    // Stripe enables automatic payment methods by default in the latest API version.
    automatic_payment_methods: { enabled: true },
    hooks: { inputs: { tax: { calculation: order.taxCalculationId } } },
  });
import 'server-only';

import Stripe from 'stripe';

export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
export async function POST(req) {
{
  "name": "stripe-sample",
  "version": "1.0.0",
  "description": "A sample Stripe implementation",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "author": "stripe-samples",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1",
    "stripe": "^23.0.0"
  }
}
{
  "name": "stripe-sample",
  "version": "0.1.0",
  "dependencies": {
    "@stripe/react-stripe-js": "^3.7.0",
    "@stripe/stripe-js": "^7.3.0",
    "express": "^4.17.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-scripts": "^3.4.0",
    "stripe": "23.0.0"
  },
  "devDependencies": {
    "concurrently": "4.1.2"
  },
  "homepage": "http://localhost:3000/checkout",
  "proxy": "http://localhost:4242",
  "scripts": {
    "start-client": "react-scripts start",
    "start-server": "node server.js",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "start": "concurrently \"npm run start-client\" \"npm run start-server\""
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
require github.com/stripe/stripe-go/v87 v87.0.0
certifi==2026.1.4
chardet==5.2.0
click==8.3.1
Flask==3.1.2
idna==3.11
itsdangerous==2.2.0
Jinja2==3.1.6
MarkupSafe==3.0.3
requests==2.32.5
stripe==16.0.0
toml==0.10.2
Werkzeug==3.1.5
{
  "name": "stripe-sample",
  "version": "0.2.0",
  "license": "ISC",
  "dependencies": {
    "@stripe/react-stripe-js": "^3.7.0",
    "@stripe/stripe-js": "^7.3.0",
    "express": "^4.21.0",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "react-router-dom": "^6.26.2",
    "react-scripts": "^5.0.1",
    "stripe": "^16.12.0"
  },
  "devDependencies": {
    "@babel/plugin-transform-private-property-in-object": "^7.25.7",
    "concurrently": "^9.0.1"
  },
  "homepage": "http://localhost:3000/checkout",
  "proxy": "http://localhost:4242",
  "scripts": {
    "start-client": "react-scripts start",
    "start-server": "node server.js",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "start": "concurrently \"yarn start-client\" \"yarn start-server\""
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
{
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@stripe/react-stripe-js": "^3.7.0",
    "@stripe/stripe-js": "^7.3.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.26.1",
    "react-scripts": "^5.0.1"
  },
  "homepage": "http://localhost:3000/checkout",
  "proxy": "http://localhost:4242",
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
1. Build the server

~~~
pip3 install -r requirements.txt
~~~
1. Build the server

~~~
bundle install
~~~
1. Build the server

~~~
composer install
~~~
1. Build the server

~~~
dotnet restore
~~~
1. Build the server

~~~
mvn package
~~~

2. Run the server

~~~
export FLASK_APP=server.py
python3 -m flask run --port=4242
~~~

2. Run the server

~~~
ruby server.rb -o 0.0.0.0
~~~

2. Run the server

~~~
php -S 127.0.0.1:4242 --docroot=public
~~~

2. Run the server

~~~
dotnet run
~~~

2. Run the server

~~~
java -cp target/sample-jar-with-dependencies.jar com.stripe.sample.Server
~~~

3. Build the client app

~~~
npm install
~~~

4. Run the client app

~~~
npm start
~~~

5. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout)

3. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html)

3. Build the client app

~~~
npm install
~~~

4. Run the client app

~~~
npm start
~~~

5. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout)

3. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html)

3. Build the client app

~~~
npm install
~~~

4. Run the client app

~~~
npm start
~~~

5. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout)

3. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html)

3. Build the client app

~~~
npm install
~~~

4. Run the client app

~~~
npm start
~~~

5. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout)

3. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html)

3. Build the client app

~~~
npm install
~~~

4. Run the client app

~~~
npm start
~~~

5. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout)

3. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html)
1. Run the server

~~~
go run server.go
~~~

2. Build the client app

~~~
npm install
~~~

3. Run the client app

~~~
npm start
~~~

4. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout)
1. Run the server

~~~
go run server.go
~~~

2. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html)
1. Build the application

~~~
npm install
~~~

2. Run the application

~~~
npm start
~~~

3. Go to [http://localhost:3000/checkout](http://localhost:3000/checkout)

\## API Keys

This code sample uses a public sample test API key. Don't submit any personally identifiable information in requests made with this key.

The "View details" link to see the PaymentIntent details in the Dashboard won't work until you use your own test [API key](https://docs.stripe.com/keys).
1. Build the server

~~~
npm install
~~~

2. Run the server

~~~
npm start
~~~

3. Go to [http://localhost:4242/checkout.html](http://localhost:4242/checkout.html)
\### Development
1. Build the application
~~~shell
$ npm install
~~~

2. Download and run the [Stripe CLI](https://stripe.com/docs/stripe-cli). The Stripe CLI is a developer tool that helps you build, test, and manage your integration with Stripe directly from the command line.
~~~shell
$ stripe listen --forward-to localhost:3000/api/webhooks
~~~

3. Run the application
~~~shell
$ STRIPE_WEBHOOK_SECRET=$(stripe listen --print-secret) npm run dev
~~~

4. Go to [localhost:3000](http://localhost:3000)

### Production
1. Build the application
~~~shell
$ npm install

$ npm build
~~~

2. Run the application
~~~shell
$ npm start
~~~
### Install the Stripe Node library

Install the package and import it in your code. Alternatively, if you’re starting from scratch and need a package.json file, download the project files using the Download link in the code editor.

#### npm

Install the library:

```bash
npm install --save stripe
```

#### GitHub

Or download the stripe-node library source code directly [from GitHub](https://github.com/stripe/stripe-node).

### Install the Stripe Ruby library

Install the Stripe ruby gem and require it in your code. Alternatively, if you’re starting from scratch and need a Gemfile, download the project files using the link in the code editor.

#### Terminal

Install the gem:

```bash
gem install stripe
```

#### Bundler

Add this line to your Gemfile:

```bash
gem 'stripe'
```

#### GitHub

Or download the stripe-ruby gem source code directly [from GitHub](https://github.com/stripe/stripe-ruby).

### Install the Stripe Java library

Add the dependency to your build and import the library. Alternatively, if you’re starting from scratch and need a sample pom.xml file (for Maven), download the project files using the link in the code editor.

#### Maven

Add the following dependency to your POM and replace {VERSION} with the version number you want to use.

```bash
<dependency>\n<groupId>com.stripe</groupId>\n<artifactId>stripe-java</artifactId>\n<version>{VERSION}</version>\n</dependency>
```

#### Gradle

Add the dependency to your build.gradle file and replace {VERSION} with the version number you want to use.

```bash
implementation "com.stripe:stripe-java:{VERSION}"
```

#### GitHub

Download the JAR directly [from GitHub](https://github.com/stripe/stripe-java/releases/latest).

### Install the Stripe Python package

Install the Stripe package and import it in your code. Alternatively, if you’re starting from scratch and need a requirements.txt file, download the project files using the link in the code editor.

#### pip

Install the package through pip:

```bash
pip3 install stripe
```

#### GitHub

Download the stripe-python library source code directly [from GitHub](https://github.com/stripe/stripe-python).

### Install the Stripe PHP library

Install the library with composer and initialize with your secret API key. Alternatively, if you’re starting from scratch and need a composer.json file, download the files using the link in the code editor.

#### Composer

Install the library:

```bash
composer require stripe/stripe-php
```

#### GitHub

Or download the stripe-php library source code directly [from GitHub](https://github.com/stripe/stripe-php).

### Set up your server

Add the dependency to your build and import the library. Alternatively, if you’re starting from scratch and need a go.mod file, download the project files using the link in the code editor.

#### Go

Make sure to initialize with Go Modules:

```bash
go get -u github.com/stripe/stripe-go/v87
```

#### GitHub

Or download the stripe-go module source code directly [from GitHub](https://github.com/stripe/stripe-go).

### Install the Stripe.net library

Install the package with .NET or NuGet. Alternatively, if you’re starting from scratch, download the files which contains a configured .csproj file.

#### dotnet

Install the library:

```bash
dotnet add package Stripe.net
```

#### NuGet

Install the library:

```bash
Install-Package Stripe.net
```

#### GitHub

Or download the Stripe.net library source code directly [from GitHub](https://github.com/stripe/stripe-dotnet).

### Install the Stripe libraries

Install the packages and import them in your code. Alternatively, if you’re starting from scratch and need a `package.json` file, download the project files using the link in the code editor.

Install the libraries:

```bash
npm install --save stripe @stripe/stripe-js next
```

### Calculate the order total

Determine the currency and calculate the order total on your server before displaying the payment form. Include tax if enabled. Return these values without creating a `PaymentIntent`. The sample uses a fixed order. In your integration, look up prices from your catalog and use the same order when creating the `PaymentIntent`.

Call the payment creation endpoint only after your customer submits the form. For Next.js, the sample uses a server action. Keep `amount`, `currency`, and `setup_future_usage` on the `PaymentIntent` consistent with the values supplied to Elements.

### Add a payment creation endpoint

Add an endpoint on your server that creates a [PaymentIntent](https://docs.stripe.com/api/payment_intents.md). A `PaymentIntent` tracks the payment lifecycle, including failed attempts, and ensures that the customer is charged only once. Return its *client secret* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)) in the response to finish the payment on the client.

### Configure payment methods

 Stripe enables cards and other common payment methods by default with [dynamic payment methods](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md). You can update and configure payment methods from the [Dashboard](https://dashboard.stripe.com/settings/payment_methods) with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and customer location.

### Configure payment methods

 Stripe enables cards and other common payment methods by default with [dynamic payment methods](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md). You can update and configure payment methods from the [Dashboard](https://dashboard.stripe.com/settings/payment_methods) with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and customer location.

### Configure payment methods

 Stripe enables cards and other common payment methods by default with [dynamic payment methods](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md). You can update and configure payment methods from the [Dashboard](https://dashboard.stripe.com/settings/payment_methods) with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and customer location.

### Configure payment methods

 Stripe enables cards and other common payment methods by default with [dynamic payment methods](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md). You can update and configure payment methods from the [Dashboard](https://dashboard.stripe.com/settings/payment_methods) with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and customer location.

### Configure payment methods

 Stripe enables cards and other common payment methods by default with [dynamic payment methods](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md). You can update and configure payment methods from the [Dashboard](https://dashboard.stripe.com/settings/payment_methods) with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and customer location.

### Configure payment methods

 Stripe enables cards and other common payment methods by default with [dynamic payment methods](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md). You can update and configure payment methods from the [Dashboard](https://dashboard.stripe.com/settings/payment_methods) with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and customer location.

### Configure payment methods

 Stripe enables cards and other common payment methods by default with [dynamic payment methods](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md). You can update and configure payment methods from the [Dashboard](https://dashboard.stripe.com/settings/payment_methods) with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and customer location.

### Configure payment methods

 Stripe enables cards and other common payment methods by default with [dynamic payment methods](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md). You can update and configure payment methods from the [Dashboard](https://dashboard.stripe.com/settings/payment_methods) with no code required. Stripe filters payment methods based on eligibility and payment method preferences, then orders and displays them by probability based on factors including amount, currency, and customer location.

### Add Stripe to your React app

Use the *Stripe.js* (Use Stripe.js’ APIs to tokenize customer information, collect sensitive card data, and accept payments with browser payment APIs) and the [Stripe Elements UI library](https://docs.stripe.com/sdks/stripejs-react.md) to stay *PCI compliant* (Any party involved in processing, transmitting, or storing credit card data must comply with the rules specified in the Payment Card Industry (PCI) Data Security Standards. PCI compliance is a shared responsibility and applies to both Stripe and your business) by ensuring that payment details go directly to Stripe and never reach your server.

```bash
npm install --save @stripe/react-stripe-js @stripe/stripe-js
```

### Add Stripe to your React app

Use the *Stripe.js* (Use Stripe.js’ APIs to tokenize customer information, collect sensitive card data, and accept payments with browser payment APIs) and the [Stripe Elements UI library](https://docs.stripe.com/sdks/stripejs-react.md) to stay *PCI compliant* (Any party involved in processing, transmitting, or storing credit card data must comply with the rules specified in the Payment Card Industry (PCI) Data Security Standards. PCI compliance is a shared responsibility and applies to both Stripe and your business) by ensuring that payment details go directly to Stripe and never reach your server.

```bash
npm install --save @stripe/react-stripe-js @stripe/stripe-js
```

### Load Stripe.js

Call `loadStripe()` with your Stripe [publishable API key](https://docs.stripe.com/keys.md#obtain-api-keys) to configure the Stripe library.

### Load Stripe.js

Call `loadStripe()` with your Stripe [publishable API key](https://docs.stripe.com/keys.md#obtain-api-keys) to configure the Stripe library.

### Load Stripe.js

Use *Stripe.js* (Use Stripe.js’ APIs to tokenize customer information, collect sensitive card data, and accept payments with browser payment APIs) to remain *PCI compliant* (Any party involved in processing, transmitting, or storing credit card data must comply with the rules specified in the Payment Card Industry (PCI) Data Security Standards. PCI compliance is a shared responsibility and applies to both Stripe and your business) by ensuring that payment details are sent directly to Stripe without hitting your server. Always load Stripe.js from js.stripe.com to remain compliant. Don’t include the script in a bundle or host it yourself.

### Define the payment form

Add one empty placeholder `div` to your checkout form for each Element that you’ll mount. Stripe inserts an iframe into each `div` to securely collect the customer’s email address and payment information.

### Initialize Stripe.js

Initialize Stripe.js with your [publishable API key](https://docs.stripe.com/keys.md#obtain-api-keys). You’ll use Stripe.js to create the payment element and complete the payment on the client.

### Load the order total

Load the amount and currency calculated by your server. Use these values to display the payment form before creating a `PaymentIntent`. With Next.js, the server component passes the order total to the checkout form.

### Initialize Stripe Elements

Pass the promise returned by `loadStripe` to the `Elements` provider so child components can access Stripe.js. Pass `mode: "payment"` and the server-calculated `amount` and `currency` as options to the `Elements` provider. If you save payment details, also pass `setupFutureUsage: "off_session"`.

### Initialize Stripe Elements

Pass the promise returned by `loadStripe` to the `Elements` provider so child components can access Stripe.js. Pass `mode: "payment"` and the server-calculated `amount` and `currency` as options to the `Elements` provider. If you save payment details, also pass `setupFutureUsage: "off_session"`.

### Initialize Stripe Elements

Initialize the [Stripe Elements UI library](https://docs.stripe.com/js/elements_object/create) with `mode: "payment"` and the server-calculated `amount` and `currency`. If you save payment details, also pass `setupFutureUsage: "off_session"`. Elements manages the UI components you need to collect payment details.

### Set up the state

Initialize state to track payment progress, display errors, and disable the form during submission.

### Set up the state

Initialize state to track payment progress, display errors, and disable the form during submission.

### Store a reference to Stripe

Access the Stripe library in your CheckoutForm component by using the `useStripe()` and `useElements()` hooks. If you need to access Elements with a class component, use the [ElementsConsumer](https://docs.stripe.com/sdks/stripejs-react.md#elements-consumer) instead.

### Store a reference to Stripe

Access the Stripe library in your CheckoutForm component by using the `useStripe()` and `useElements()` hooks. If you need to access Elements through a class component, use the [ElementsConsumer](https://docs.stripe.com/sdks/stripejs-react.md#elements-consumer) instead.

### Add the payment element

Add [PaymentElement](https://docs.stripe.com/js/elements_object/create_payment_element) to your payment form. It embeds an iframe with a dynamic form that collects payment details for a variety of payment methods. Your customer can pick a payment method type, and the form automatically collects the required payment details for their selection.

### Add the payment element

Add the [PaymentElement](https://docs.stripe.com/js/elements_object/create_payment_element) to your payment form. It embeds an iframe with a dynamic form that collects payment details for a variety of payment methods. Your customer can pick a payment method type, and the form automatically collects the required payment details for their selection.

### Create the payment element

Create a [PaymentElement](https://docs.stripe.com/js/elements_object/create_payment_element) and mount it to the placeholder `<div>` in your payment form. This embeds an iframe with a dynamic form that displays payment methods available for the configured amount and currency, allowing your customer to select a payment method. The form automatically collects the associated payment details for the selected payment method type.

### (Optional) Style the payment element

Customize the payment element UI by creating an [Appearance object](https://docs.stripe.com/elements/appearance-api.md) and passing it as an option to the `Elements` provider. Use your company’s color scheme and font to make it match with the rest of your checkout page. Use custom fonts (for example, from Google Fonts) by initializing Elements with a [font set](https://docs.stripe.com/js/elements_object/create#stripe_elements-options-fonts).

Open the preview to see your changes.

> Parts of the preview demo might not match your actual checkout page. The appearance picker exposes a subset of the [Appearance object’s](https://docs.stripe.com/elements/appearance-api.md) variables, and the [Appearance object](https://docs.stripe.com/elements/appearance-api.md) only controls certain attributes of Stripe Elements. You’re responsible for styling the rest of your checkout page.

### (Optional) Style the payment element

Customize the payment element UI by creating an [Appearance object](https://docs.stripe.com/elements/appearance-api.md) and passing it as an option to the `Elements` provider. Use your company’s color scheme and font to make it match with the rest of your checkout page. Use custom fonts (for example, from Google Fonts) by initializing Elements with a [font set](https://docs.stripe.com/js/elements_object/create#stripe_elements-options-fonts).

Open the preview to see your changes.

> Parts of the preview demo might not match your actual checkout page. The appearance picker exposes a subset of the Appearance object’s variables, and the Appearance object only controls certain attributes of Stripe Elements. You’re responsible for styling the rest of your checkout page.

### (Optional) Style the payment element

Customize the payment element UI by creating an [Appearance object](https://docs.stripe.com/elements/appearance-api.md) and initializing Elements with it. Use your company’s color scheme and font to make it match with the rest of your checkout page. Use custom fonts (for example, from Google Fonts) by initializing Elements with a [font set](https://docs.stripe.com/js/elements_object/create#stripe_elements-options-fonts).

Open the preview to see your changes.

> Parts of the preview demo might not match your actual checkout page. The appearance picker exposes a subset of the [Appearance object’s](https://docs.stripe.com/elements/appearance-api.md) variables, and the [Appearance object](https://docs.stripe.com/elements/appearance-api.md) only controls certain attributes of Stripe Elements. You’re responsible for styling the rest of your checkout page.

### Handle the submit event

Listen to the form’s submit event to know when to confirm the payment through the Stripe API.

### Validate payment details

Call [elements.submit](https://docs.stripe.com/js/elements/submit) to validate the form and collect any wallet details. If it returns an error, display the error and let your customer try again before creating a `PaymentIntent`.

### Create the PaymentIntent on submission

After `elements.submit()` succeeds, call your server to create the `PaymentIntent` and return its client secret. Handle server or network errors so your customer can retry.

### Complete the payment

Call [confirmPayment](https://docs.stripe.com/js/payment_intents/confirm_payment) with the Elements instance and the returned `clientSecret`, and pass a [return_url](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-return_url) to indicate where Stripe redirects the customer after they complete the payment. For payments that require authentication, Stripe displays a modal for *3D Secure* (3D Secure (3DS) provides an additional layer of authentication for credit card transactions that protects businesses from liability for fraudulent card payments) authentication or redirects the customer to an authentication page, depending on the payment method. After the customer completes the authentication process, they’re redirected to the `return_url`.

### Complete the payment

Call [confirmPayment](https://docs.stripe.com/js/payment_intents/confirm_payment) with the Elements instance and the returned `clientSecret`, and pass a [return_url](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-return_url) to indicate where Stripe redirects the customer after they complete the payment. For payments that require authentication, Stripe displays a modal for *3D Secure* (3D Secure (3DS) provides an additional layer of authentication for credit card transactions that protects businesses from liability for fraudulent card payments) authentication or redirects the customer to an authentication page, depending on the payment method. After the customer completes the authentication process, they’re redirected to the `return_url`.

### Complete the payment

Call [confirmPayment](https://docs.stripe.com/js/payment_intents/confirm_payment) with the Elements instance, the returned `clientSecret`, and a [return_url](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-return_url) to indicate where Stripe redirects the customer after they complete the payment. For payments that require authentication, Stripe displays a modal for *3D Secure* (3D Secure (3DS) provides an additional layer of authentication for credit card transactions that protects businesses from liability for fraudulent card payments) authentication or redirects the customer to an authentication page, depending on the payment method. After the customer completes the authentication process, they’re redirected to the `return_url`.

### Handle errors

If there are any immediate [errors](https://docs.stripe.com/error-codes.md) (for example, your customer’s card is declined), Stripe.js returns an error. Show that error message to your customer so they can try again.

### Show a payment status message

When Stripe redirects the customer to the `return_url`, the `payment_intent_client_secret` query parameter is appended by Stripe.js. Use this to retrieve the [PaymentIntent status update](https://docs.stripe.com/payments/payment-intents/verifying-status.md) and determine what to show to your customer.

### Show a payment status message

When Stripe redirects the customer to the `return_url`, the `payment_intent` query parameter is appended by Stripe.js. Use this to retrieve the [PaymentIntent status update](https://docs.stripe.com/payments/payment-intents/verifying-status.md) and determine what to show to your customer.

### Use a webhook

Stripe sends multiple events during the payment process and after the payment is complete. Create an [event destination](https://docs.stripe.com/events/set-up-events.md) for a [webhook endpoint](https://docs.stripe.com/webhooks/quickstart.md) to receive these events and run actions, such as sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow. Stripe recommends handling the [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.succeeded), [payment_intent.processing](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.processing), and [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.payment_failed) events.

Verify [webhook signatures](https://docs.stripe.com/webhooks.md#verify-events) to confirm that events came from Stripe. If your webhook endpoint uses an IP allowlist, include Stripe’s [webhook IP addresses](https://docs.stripe.com/ips.md#webhook-notifications).

Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events is what enables you to accept [different types of payment methods](https://stripe.com/payments/payment-methods-guide) with a single integration.

### Run the application

Run the React app and the server. Go to [localhost:3000/checkout](http://localhost:3000/checkout) to see your checkout page.

```bash
npm start
```

### Run the application

Run the Next.js app. Go to [localhost:3000](http://localhost:3000) to see your checkout page.

```bash
npm run dev
```

### Run the application

Run your Node server and go to [localhost:4242/checkout.html](http://localhost:4242/checkout.html).

```bash
npm start
```

### Run the server application

Run the React app and the server. Go to [localhost:3000/checkout](http://localhost:3000/checkout) to see your checkout page.

```bash
ruby server.rb
```

### Run the application

Run your Ruby server and go to [localhost:4242/checkout.html](http://localhost:4242/checkout.html).

```bash
ruby server.rb
```

### Run the server application

Run the React app and the server. Go to [localhost:3000/checkout](http://localhost:3000/checkout) to see your checkout page.

```bash
python3 -m flask run --port=4242
```

### Run the application

Run your Python server and go to [localhost:4242/checkout.html](http://localhost:4242/checkout.html).

```bash
python3 -m flask run --port=4242
```

### Run the server application

Run the React app and the server. Go to [localhost:3000/checkout](http://localhost:3000/checkout) to see your checkout page.

```bash
php -S 127.0.0.1:4242 --docroot=public
```

### Run the application

Run your server and go to [localhost:4242/checkout.html](http://localhost:4242/checkout.html).

```bash
php -S 127.0.0.1:4242 --docroot=public
```

### Run the server application

Run the React app and the server. Go to [localhost:3000/checkout](http://localhost:3000/checkout) to see your checkout page.

```bash
go run server.go
```

### Run the application

Run your Go server and go to [localhost:4242/checkout.html](http://localhost:4242/checkout.html).

```bash
go run server.go
```

### Run the server application

Run the React app and the server. Go to [localhost:3000/checkout](http://localhost:3000/checkout) to see your checkout page.

```bash
dotnet run
```

### Run the application

Run your ASP.NET MVC server and go to [localhost:4242/checkout.html](http://localhost:4242/checkout.html).

```bash
dotnet run
```

### Run the application

Run your server and go to [localhost:4242/checkout.html](http://localhost:4242/checkout.html).

```bash
java -cp target/sample-jar-with-dependencies.jar com.stripe.sample.Server
```

### Run the server application

Run the React app and the server. Go to [localhost:3000/checkout](http://localhost:3000/checkout) to see your checkout page.

```bash
java -cp target/sample-jar-with-dependencies.jar com.stripe.sample.Server
```

### Run the application

Run the React app and go to [localhost:3000/checkout](http://localhost:3000/checkout).

```bash
npm start
```

### Make a test payment

To verify that your integration works, make a test payment using [test payment details](https://docs.stripe.com/testing.md#cards).

### See your payment in the Dashboard

Go to the [Stripe Dashboard](https://dashboard.stripe.com/test/payments) to see your test payment.

## Accept payments and enhance your integration

You’re ready to accept payments with Stripe. Use the following steps to add more features.

### Automate tax collection

Calculate and collect the right amount of tax on your Stripe transactions. Before using Stripe Tax, you need to activate it in the [Dashboard](https://dashboard.stripe.com/tax). Learn more about [Stripe Tax](https://docs.stripe.com/tax.md) and [how to add it to your Payments integration](https://docs.stripe.com/tax/standalone-tax-api.md).

### Use the Stripe Tax API to calculate tax

Use the [Stripe Tax API](https://docs.stripe.com/api/tax/calculations/create.md) to calculate tax on the transaction. Provide the `currency`, `customer_details`, and the `line_items` of the order in the request body.

Use the tax calculation’s `tax_amount_exclusive` value to add exclusive tax to the order total.

### Record a tax transaction after a successful payment

Link the tax calculation to the `PaymentIntent` using `hooks[inputs][tax][calculation]`.

This records the collected tax in your Stripe account for accounting exports and triggers other [Stripe actions](https://docs.stripe.com/tax/payment-intent/simplified.md#automatic-actions).

### Send an email receipt

Stripe can send an email receipt to your customer using your brand logo and color theme, which are configurable in the [Dashboard](https://dashboard.stripe.com/settings/branding).

### Collect the customer’s email address

Add an input field to your payment form to collect the email address.

### Add email to the state

Add a variable to keep track of the email the customer enters.

### Add email to the state

Add a variable to keep track of the email the customer enters.

### Provide the email address to Stripe

Pass the provided email address as the `receipt_email` value. Stripe sends an email receipt when the payment succeeds in live mode (but won’t send one in a *sandbox* (A sandbox is an isolated test environment that allows you to test Stripe functionality in your account without affecting your live integration. Use sandboxes to safely experiment with new features and changes)).

### Save payment details after payment

Often used by SaaS or e-commerce businesses with recurring customers.

### Import additional Stripe resources

Import the Stripe `customer` and `paymentmethod` packages. Use these packages to store information about your customer.

### Import additional Stripe resources

Import the Stripe PaymentMethod and Customer models. Use these models to store information about your Customer.

### Create a customer

Stripe stores the card on a *Customer* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) object. Create a new Customer before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Customer.

### Create a customer

Stripe stores the card on an [Account](https://docs.stripe.com/api/v2/core/accounts/object.md) object representing the [customer](https://docs.stripe.com/connect/account-capabilities.md?accounts-namespace=v2#customer). Create a new Account before creating a PaymentIntent. You can also store name, email, shipping address, and other details on the Account.

### Add the customer to the PaymentIntent

Pass the Customer ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method—certain regions, such as Europe and India, have requirements around reusing payment details. [Learn more](https://docs.stripe.com/payments/payment-intents.md#future-usage) about the most effective way to apply `setup_future_usage`. You can also view a [list of supported payment methods](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#additional-api-supportability). After the PaymentIntent succeeds, Stripe automatically [attaches](https://docs.stripe.com/api/payment_methods/attach.md) the payment details (in a *PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) object) to your Customer.

### Add the customer to the PaymentIntent

Pass the Account ID to the PaymentIntent and set `setup_future_usage` to `off_session`. `setup_future_usage` tells Stripe how you plan to use the payment method—certain regions, such as Europe and India, have requirements around reusing payment details. [Learn more](https://docs.stripe.com/payments/payment-intents.md#future-usage) about the most effective way to apply `setup_future_usage`. You can also view a [list of supported payment methods](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#additional-api-supportability). After the PaymentIntent succeeds, Stripe automatically [attaches](https://docs.stripe.com/api/payment_methods/attach.md) the payment details (in a *PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) object) to the customer-configured Account.

### Charge the saved PaymentMethod

When you’re ready to charge the PaymentMethod again, create a new PaymentIntent with the Customer ID, the ID of the PaymentMethod you want to charge, and set the `off_session` and `confirm` flags to true.

## Next steps

#### [Collect billing address details](https://docs.stripe.com/elements/address-element.md)

By default, the Payment Element only collects the necessary billing address details. To collect a customer’s full billing address (to calculate the tax for digital goods and services, for example) or shipping address, use the Address Element.

#### [Payouts](https://docs.stripe.com/payouts.md)

Learn how to move funds out of your Stripe account into your bank account.

#### [Refunds](https://docs.stripe.com/refunds.md)

Handle requests for refunds by using the Stripe API or Dashboard.

#### [Fulfillment](https://docs.stripe.com/webhooks/quickstart.md)

Create an event destination to send events to your webhook endpoint to fulfill orders after a payment succeeds, and to handle other critical events.
