# Payment Element and PaymentIntents — Stripe Payments

Source: https://www.skillbyai.com/en/stripe-payments/a-element

> An embedded form confirmed in the browser.

## Client secret and client-side confirmation

The **Payment Element** is a UI component from Stripe.js that renders inside your own page and shows the payment methods available for the customer. The server creates a **PaymentIntent** with the amount and currency and returns its **client secret** to the browser. The browser initialises Elements with that client secret, mounts the Payment Element and calls `stripe.confirmPayment`, which sends the details directly to Stripe, handles any 3D Secure challenge and redirects to your `return_url`. Never compute the amount in the browser: the server decides the price.

## Server and browser halves

Node.js on the server, Stripe.js in the browser.

```javascript
// server: create the PaymentIntent
app.post('/create-payment-intent', async (req, res) => {
  const amount = await priceForCart(req.user.cartId); // server-side total
  const intent = await stripe.paymentIntents.create({
    amount,
    currency: 'usd',
    automatic_payment_methods: { enabled: true },
    metadata: { cartId: req.user.cartId },
  });
  res.json({ clientSecret: intent.client_secret });
});

// browser: mount the Payment Element and confirm
const stripe = Stripe('pk_test_...');
const { clientSecret } = await (await fetch('/create-payment-intent', { method: 'POST' })).json();
const elements = stripe.elements({ clientSecret });
elements.create('payment').mount('#payment-element');

form.addEventListener('submit', async (e) => {
  e.preventDefault();
  const { error } = await stripe.confirmPayment({
    elements,
    confirmParams: { return_url: 'https://example.com/order/complete' },
  });
  if (error) showMessage(error.message); // otherwise the browser is redirected
});

```

## Treat the client secret carefully

The client secret lets the browser confirm that one PaymentIntent. Send it only to the customer who owns the payment, over HTTPS, and do not log or store it.

**Quiz:** What does the server send to the browser so it can confirm a PaymentIntent?

- [ ] The secret API key
- [x] The PaymentIntent's client_secret
- [ ] The raw card number
- [ ] The webhook signing secret

*Answer:* The PaymentIntent's client_secret. The client secret is scoped to a single PaymentIntent.
