# Payments for existing customers

Learn how to charge an existing payment method while a customer is on-session.

# Direct API


To completely control how you display existing Payment Methods, use the Direct API implementation.

## Display Payment Methods [Client-side] [Server-side]

Call the [list Payment Method](https://docs.stripe.com/api/payment_methods/customer_list.md) endpoint with the `allow_redisplay` parameter to retrieve a the reusable payment methods associated with a customer.

#### Accounts v2

```curl
curl -G https://api.stripe.com/v1/payment_methods \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d customer_account={{CUSTOMER_ACCOUNT_ID}} \
  -d allow_redisplay=always
```

#### Customers v1

```curl
curl -G https://api.stripe.com/v1/customers/{{CUSTOMER_ID}}/payment_methods \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d allow_redisplay=always
```

Use the API response data to display the Payment Methods in your own UI and let the customer select one.

## Optional: Display additional saved payment methods [Server-side]

> #### Compliance
> 
> You’re responsible for your compliance with all applicable laws, regulations, and network rules when saving a customer’s payment details. When rendering past payment methods to a customer for future purchases, make sure you’ve collected consent to save the payment method details for this specific future use.

By default, we only show payment methods set to [always allow redisplay](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay).

You can’t reuse Apple Pay and Google Pay during a Checkout Session, so these payment methods don’t appear in the list of saved options. You must display the Google Pay and Apple Pay UI, and the payment request button UI, each time the Checkout Session is active.

You can display other previously saved payment methods by including other redisplay values in the Checkout Session, or by updating a payment method’s `allow_redisplay` setting to `always`.

- Use the `allow_redisplay` [parameter](https://docs.stripe.com/api/payment_methods/customer_list.md#list_customer_payment_methods-allow_redisplay) to specify which saved payment methods to show the customer. You can set any of the valid values: `limited`, `unspecified` and `always`.

  #### Accounts v2

  ```curl
  curl -G https://api.stripe.com/v1/payment_methods \
    -u "<<YOUR_SECRET_KEY>>:" \
    -d "customer_account={{CUSTOMERACCOUNT_ID}}" \
    -d allow_redisplay=unspecified
  ```

  #### Customers v1

  ```curl
  curl -G https://api.stripe.com/v1/customers/{{CUSTOMER_ID}}/payment_methods \
    -u "<<YOUR_SECRET_KEY>>:" \
    -d allow_redisplay=unspecified
  ```

- [Update the Payment Method](https://docs.stripe.com/api/payment_methods/update.md) to set the `allow_redisplay` value on individual payment methods.
  ```curl
  curl https://api.stripe.com/v1/payment_methods/{{PAYMENTMETHOD_ID}} \
    -u "<<YOUR_SECRET_KEY>>:" \
    -d allow_redisplay=always
  ```

## Create PaymentIntent [Server-side]

Create a [PaymentIntent](https://docs.stripe.com/api/payment_intents/create.md) to try to charge the customer with the payment method they selected.

#### Accounts v2

```curl
curl https://api.stripe.com/v1/payment_intents \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d amount=1099 \
  -d currency=usd \
  -d customer_account={{CUSTOMER_ACCOUNT_ID}} \
  -d payment_method={{PAYMENT_METHOD_ID}} \
  -d confirm=true \
  --data-urlencode "return_url=https://example.com/order/123/complete"
```

#### Customers v1

```curl
curl https://api.stripe.com/v1/payment_intents \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d amount=1099 \
  -d currency=usd \
  -d customer={{CUSTOMER_ID}} \
  -d payment_method={{PAYMENT_METHOD_ID}} \
  -d confirm=true \
  --data-urlencode "return_url=https://example.com/order/123/complete"
```

If the API call fails with a 402 response, it means the payment was declined. Ask the customer to try again or use a different payment method.

## Check PaymentIntent status [Client-side] [Server-side]

Assuming the PaymentIntent is successfully created, check its `status`:

- `succeeded` indicates the customer was charged as expected. Display a success message to your customer.
- `requires_action` indicates you must prompt additional action, such as authenticating with 3D Secure. Call [`handleNextAction`](https://docs.stripe.com/js/payment_intents/handle_next_action) on the frontend to trigger the action the customer needs to perform.

```javascript
const { error, paymentIntent } = await stripe.handleNextAction({
  clientSecret: "{{CLIENT_SECRET}}"
});

if (error) {
  // Show error from Stripe.js
} else {
  // Actions handled, show success message
}
```

## Handle post-payment events [Server-side]

Stripe sends a [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) event when the payment completes. Use the [Dashboard webhook tool](https://dashboard.stripe.com/webhooks) or follow the [webhook guide](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.

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.

In addition to handling the `payment_intent.succeeded` event, we recommend handling these other events when collecting payments with the Payment Element:

| Event                                                                                                                           | Description                                                                                                                                                                                                                                                                         | Action                                                                                                                                                                                           |
| ------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.succeeded)           | Sent when a customer successfully completes a payment.                                                                                                                                                                                                                              | Send the customer an order confirmation and *fulfill* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected) their order. |
| [payment_intent.processing](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.processing)         | Sent when a customer successfully initiates a payment, but the payment has yet to complete. This event is most commonly sent when the customer initiates a bank debit. It’s followed by either a `payment_intent.succeeded` or `payment_intent.payment_failed` event in the future. | Send the customer an order confirmation that indicates their payment is pending. For digital goods, you might want to fulfill the order before waiting for payment to complete.                  |
| [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.payment_failed) | Sent when a customer attempts a payment, but the payment fails.                                                                                                                                                                                                                     | If a payment transitions from `processing` to `payment_failed`, offer the customer another attempt to pay.                                                                                       |

