# Introduction to server-side SDKs

Learn how to install and use the Stripe server-side SDKs.

The Stripe server-side SDKs reduce the amount of work required to use our REST APIs. Stripe-maintained SDKs are available for Ruby, PHP, Java, Python, Node, .NET and Go. [Community libraries](https://docs.stripe.com/sdks/community.md) are also available for other server languages.

## Installation and setup 

Select your language in the language selector below, then follow the instructions to install the SDK.

#### Python

```bash
# Install through pip
pip3 install --upgrade stripe
```

```bash
# Or find the Stripe package on http://pypi.python.org/pypi/stripe/
```

```python
# Find the version you want to pin:
# https://github.com/stripe/stripe-python/blob/master/CHANGELOG.md
# Specify that version in your requirements.txt file
stripe>=5.0.0
```

After completing the installation, you need to initialize Stripe:

#### Python

```python
from stripe import StripeClient
# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
client = StripeClient("<<YOUR_SECRET_KEY>>")
```

## Send API requests 

You can manipulate objects with the Stripe API in six primary ways: create, update, delete, retrieve, list, and search. The following examples show each of the six ways using the `Customer` object:

#### Create

Create a customer named John Doe.

```python
# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = StripeClient("<<YOUR_SECRET_KEY>>")

# For SDK versions 12.4.0 or lower, remove '.v1' from the following line.
customer = client.v1.customers.create({"name": "John Doe"})
```

#### Update

Retrieve a customer with a specific ID.

```python
# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = StripeClient("<<YOUR_SECRET_KEY>>")

# For SDK versions 12.4.0 or lower, remove '.v1' from the following line.
customer = client.v1.customers.update(
  "{{CUSTOMER_ID}}",
  {"email": "jdoe@example.com"},
)
```

#### Delete

Delete a customer with a specific ID.

```python
# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = StripeClient("<<YOUR_SECRET_KEY>>")

# For SDK versions 12.4.0 or lower, remove '.v1' from the following line.
deleted = client.v1.customers.delete("{{CUSTOMER_ID}}")
```

#### Retrieve

Retrieve a customer with a specific ID.

```python
# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = StripeClient("<<YOUR_SECRET_KEY>>")

# For SDK versions 12.4.0 or lower, remove '.v1' from the following line.
customer = client.v1.customers.retrieve("{{CUSTOMER_ID}}")
```

#### List

List the 5 most recently created customers.

```python
# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = StripeClient("<<YOUR_SECRET_KEY>>")

# For SDK versions 12.4.0 or lower, remove '.v1' from the following line.
customers = client.v1.customers.list({"limit": 5})
```

#### Search

Search for customers named Jane Doe.

```python
# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = StripeClient("<<YOUR_SECRET_KEY>>")

# For SDK versions 12.4.0 or lower, remove '.v1' from the following line.
customers = client.v1.customers.search({"query": "name:'Jane Doe'"})
```

API requests can contain different types of parameters. For example, here’s how to create a customer with a `name` (a string), `address` (an object), and `preferred_locales` (a list):

```python
# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = StripeClient("<<YOUR_SECRET_KEY>>")

# For SDK versions 12.4.0 or lower, remove '.v1' from the following line.
customer = client.v1.customers.create({
  "name": "John Doe",
  "address": {"country": "US", "city": "San Fransisco"},
  "preferred_locales": ["EN", "FR"],
})
```

When updating an object, you can clear some of its properties. For dynamically typed languages, send an empty string. For strongly typed languages, use specific constants. For example, here’s how to clear the `name` (a string) and `metadata` (a hash of key-value pairs) of a customer:

#### Python

```python
customer = client.v1.customers.update(
  '{{CUSTOMER_ID}}',
  params={
    'name': '',
    'metadata': '',
  },
)
```

This example clears all metadata, but you can also clear individual keys. Learn more about managing metadata in our [metadata guide](https://docs.stripe.com/metadata.md).

## Access the API response 

Every time you make an API request, Stripe sends you back a response.

If you create, retrieve, or update an object, you get back the object itself:

```json
{
  "id": "pi_001",
  "object": "payment_intent",
  "amount": 1099,
  "currency": "usd",
  /* ... */
}
```

Use a variable to access the properties of that object:

#### Python

```python
paymentIntent = client.v1.payment_intents.retrieve("{{PAYMENT_INTENT_ID}}")
print(paymentIntent.amount)
```

When listing or searching for objects, you get back a `List` object containing a `data` array with the objects requested:

```json
{
  "object": "list",
  "data": [
    {
      "id": "pi_003",
      "object": "payment_intent",
      "amount": 4200,
      "currency": "usd",
      /* ... */
    },
    {
      "id": "pi_002",
      "object": "payment_intent",
      "amount": 2100,
      "currency": "usd",
      "payment_method_types": [ "link" ],
      /* ... */
    }
  ],
  "has_more": true,
  "url": "/v1/payment_intents"
}
```

Use a loop on the `data` array to access the properties of each object:

#### Python

```python
paymentIntentList = client.v1.payment_intents.list(params={"limit": 3})
for pi in paymentIntentList.data:
  print(pi.amount)
```

You could also use [auto-pagination](https://docs.stripe.com/pagination.md#auto-pagination) to iterate over all the results.

## Expanding responses 

Some properties are expandable or includable, meaning you can return them by using the `expand` parameter. For example:

- Retrieve a PaymentIntent and expand its associated PaymentMethod.
  ```python
  # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
  # Find your keys at https://dashboard.stripe.com/apikeys.
  client = StripeClient("<<YOUR_SECRET_KEY>>")
  
  # For SDK versions 12.4.0 or lower, remove '.v1' from the following line.
  payment_intent = client.v1.payment_intents.retrieve(
    "{{PAYMENT_INTENT_ID}}",
    {"expand": ["payment_method"]},
  )
  ```
- Retrieve a Checkout Session and include the `line_items` property.
  ```python
  # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
  # Find your keys at https://dashboard.stripe.com/apikeys.
  client = StripeClient("<<YOUR_SECRET_KEY>>")
  
  # For SDK versions 12.4.0 or lower, remove '.v1' from the following line.
  session = client.v1.checkout.sessions.retrieve(
    "{{SESSION_ID}}",
    {"expand": ["line_items"]},
  )
  ```

Learn more about [expanding responses](https://docs.stripe.com/expand.md).

## Retrieve the request ID 

Each API request has a unique request ID (`req_xxx`) associated with it. You can use it to inspect the request in the Dashboard to see the parameters Stripe received, or to share it with Stripe support when you need to resolve an issue.

You can find the IDs in your [Dashboard logs](https://dashboard.stripe.com/test/workbench/logs), or directly with code like this:

#### Python

```python
customer = client.v1.customers.create(params={"name": "John Doe"})
print(customer.last_response.request_id)
```

## Set additional request options 

When sending API requests, you can set additional request options to:

- [Set a specific API version](https://docs.stripe.com/sdks/set-version.md).
- [Make requests on your connected accounts](https://docs.stripe.com/connect/authentication.md).
- [Provide idempotency keys](https://docs.stripe.com/api/idempotent_requests.md).

## Error handling 

Each server SDK interprets error responses from the Stripe API as exception types, so you don’t need to parse the response status yourself. Use error handling conventions appropriate for each language to handle those errors.

#### Python

```python
try:
  client.v1.payment_intents.create(params=kwargs)
except stripe.error.CardError as e:
  logging.error("A payment error occurred: {}".format(e.user_message))
except stripe.error.InvalidRequestError:
  logging.error("An invalid request occurred.")
except Exception:
  logging.error("Another problem occurred, maybe unrelated to Stripe.")
else:
  logging.info("No error.")
```

Learn more about [error handling](https://docs.stripe.com/error-handling.md).

## Undocumented params and fields 

In some cases, you might encounter parameters on an API request or fields on an API response that aren’t available in the SDKs. This might happen when they’re undocumented or when they’re in preview and you aren’t using a preview SDK. Use the following guidance to send those parameters or access those fields.

### Send undocumented parameters

In the following example, you create a `Customer` with an undocumented boolean parameter. The code example uses `secret_feature_enabled`, which the SDKs don’t expose.

#### Python

```python
# If using a type checker, use # type: ignore or # pyright: ignore
# to ignore the type error for the new param not existing in the SDK
customer = client.v1.customers.create({
  "email": "jennyrosen@example.com",
  "secret_feature_enabled": "true",
})
```

### Access undocumented fields

In the following example, you read an undocumented boolean field on the `Customer` object. The code sample uses `secret_feature_enabled`, which the SDKs don’t expose.

#### Python

```python
customer = client.v1.customers.retrieve("cus_1234")
# If using a type checker, use # type: ignore or # pyright: ignore
# to ignore the type error for the new field not existing in the SDK
secret_feature_enabled = customer.secret_feature_enabled
```

## Source code

The source code for each of our server SDKs is available on GitHub:

| Language   | Repository                                                 |
| ---------- | ---------------------------------------------------------- |
| **Ruby**   | [`stripe-ruby`](https://github.com/stripe/stripe-ruby)     |
| **PHP**    | [`stripe-php`](https://github.com/stripe/stripe-php)       |
| **Java**   | [`stripe-Java`](https://github.com/stripe/stripe-java)     |
| **Node**   | [`stripe-node`](https://github.com/stripe/stripe-node)     |
| **Python** | [`stripe-python`](https://github.com/stripe/stripe-python) |
| **.NET**   | [`stripe-dotnet`](https://github.com/stripe/stripe-dotnet) |
| **Go**     | [`stripe-go`](https://github.com/stripe/stripe-go)         |

## StripeClient

The `StripeClient` class acts as an entry point to help you discover resources and make requests to the Stripe API. The benefits of using this pattern over the older one that used global configuration are:

- You can simultaneously use multiple clients with different configuration options (such as API keys).
- It enables easier mocking during testing as `StripeClient` doesn’t use static methods.
- No extra API calls. In some languages, you had to call a retrieve before doing an update or delete. When using `StripeClient`, you can access all API endpoints with a single method call.

The Node.js SDK has always had the `Stripe` class which followed the same pattern. For rest of the languages, the new pattern was added in the following SDK versions. If you’re comparing code targeting older versions of these libraries with older patterns, the calls might look different.

| Migration guides                                                                                                                            | StripeClient release |
| ------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| [stripe-php migration guide](https://github.com/stripe/stripe-php/wiki/Migration-to-StripeClient-and-services-in-7.33.0)                    | 7.33.0               |
| [stripe-python migration guide](https://github.com/stripe/stripe-python/wiki/Migration-guide-for-v8-\(StripeClient\))                       | 8.0.0                |
| [stripe-java migration guide](https://github.com/stripe/stripe-java/wiki/Migration-guide-for-v23#stripeclient)                              | 23.0.0               |
| [stripe-ruby migration guide](https://github.com/stripe/stripe-ruby/wiki/Migration-guide-for-v13)                                           | 13.0.0               |
| [stripe-dotnet migration guide](https://github.com/stripe/stripe-dotnet/blob/master/CHANGELOG.md#stripeclient)                              | 46.0.0               |
| [stripe-go migration guide](https://github.com/stripe/stripe-go/wiki/Migration-guide-for-Stripe-Client#migrating-from-global-configuration) | 82.1.0               |

## Public and private preview versions 

Stripe has features in the [public and private preview phases](https://docs.stripe.com/release-phases.md) that you can access through versions of the SDKs with the [`beta` or `b` suffix](https://docs.stripe.com/sdks/versioning.md#public-preview-release-channel) and the [`alpha` or `a` suffix](https://docs.stripe.com/sdks/versioning.md#private-preview-release-channel), respectively.
