# Crie uma página de assinatura pré-integrada com o Stripe Checkout

# Página de assinatura pré-integrada com o Stripe Checkout

Comece a usar nosso aplicativo de teste para executar uma integração de assinaturas completa e operacional usando [Stripe Billing](https://docs.stripe.com/billing.md) e [Stripe Checkout](https://docs.stripe.com/payments/checkout.md).

O exemplo de aplicativo demonstra como redirecionar seus clientes do seu site para uma página de pagamento pré-integrada e hospedada na Stripe. As APIs do Stripe Billing criam e gerenciam assinaturas, faturas e pagamentos recorrentes, e o Checkout oferece a IU pré-integrada, segura e hospedada pela Stripe para coletar dados de pagamento.

Você pode representar os clientes na sua integração como objetos [Account configurados pelo cliente](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer) ou como objetos [Customer](https://docs.stripe.com/api/customers/object.md). Para obter mais informações sobre as diferenças entre essas opções, consulte [Usar Accounts como clientes](https://docs.stripe.com/accounts-v2/use-accounts-as-customers.md).

Clique em cada etapa para ver o exemplo de código correspondente. Conforme você interage com as etapas, como adicionar dados de preços, o criador atualiza o exemplo de código.

Baixe o exemplo de aplicativo e personalize-o localmente para testar sua integração.

### Adicione produtos e preços

Crie ou selecione *Products* (Products represent what your business sells—whether that's a good or a service) e *Prices* (Prices define how much and how often to charge for products. This includes how much the product costs, what currency to use, and the interval if the price is for subscriptions) que você possa usar neste exemplo.

> Entre na sua conta Stripe para configurar produtos e preços.

### Adicione recursos ao produto

Crie recursos, como um presente de aniversário anual, e associe-os à sua assinatura para [dar direito](https://docs.stripe.com/billing/entitlements.md) a eles aos novos assinantes.

Monitore os [eventos de resumo de direitos ativos](https://docs.stripe.com/billing/entitlements.md#webhooks) no seu [destino de eventos](https://docs.stripe.com/event-destinations.md) e use a [API de listagem de direitos ativos](https://docs.stripe.com/api/entitlements/active-entitlement/list.md) para um determinado cliente para cumprir os direitos do seu cliente.

### (Opcional) Habilite formas de pagamento adicionais

Use o [Dashboard](https://dashboard.stripe.com/settings/payment_methods) para habilitar as [formas de pagamento aceitas](https://docs.stripe.com/payments/payment-methods/payment-method-support.md) que você deseja aceitar além dos cartões. O Checkout exibe dinamicamente as formas de pagamento habilitadas em ordem de relevância, de acordo com a localização do cliente e outras características.

### Adicionar uma página de prévia de preços

Adicione uma página ao site que exiba o produto e permita que os clientes o assinem. Ao clicar em **Checkout**, o cliente será redirecionado para uma página do [Checkout](https://docs.stripe.com/payments/checkout.md) hospedada pela Stripe, que finaliza o pedido e impede modificações adicionais.

Considere a possibilidade de incorporar uma [tabela de planos de preços](https://docs.stripe.com/payments/checkout/pricing-table.md) para exibir dinamicamente suas informações de planos de preços por meio do Dashboard. Ao clicar em uma opção de planos de preços, você redireciona o cliente para a página de pagamentos.

### Adicionar um botão de checkout

O botão na página de prévia do pedido redireciona o cliente para a página de pagamentos hospedada pela Stripe e usa a `lookup_key` do seu produto para recuperar o `price_id` do servidor.

### Adicionar uma página de sucesso

Crie uma página de finalização para exibir ao cliente mensagens de confirmação de pedido ou detalhes do pedido. Associe esta página à `success_url` da sessão do Checkout, para a qual a Stripe redireciona depois que o cliente finaliza o checkout.

### Adicionar um botão para o portal de clientes

Adicione um botão de redirecionamento ao portal de clientes para que o cliente possa gerenciar sua assinatura. Quando o cliente clica nesse botão, é encaminhado à página do portal de clientes hospedada pela Stripe.

### Redirecionar para a sessão no portal de clientes

Faça uma solicitação ao endpoint do servidor para redirecionar a uma nova sessão do portal do cliente. Este exemplo usa o `session_id` da [sessão do Checkout](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-id) para demonstrar a recuperação de `customer_id`. Em um ambiente de produção, recomendamos que você armazene esse valor junto com o usuário autenticado no banco de dados.

### Instale a biblioteca Node da Stripe

Instale o pacote e importe-o para seu código. Se estiver começando do zero e precisar de um arquivo package.json, baixe os arquivos do projeto pelo link de download no editor de código.

#### npm

Instale a biblioteca:

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

#### GitHub

Ou baixe o código-fonte da biblioteca stripe-node diretamente [do GitHub](https://github.com/stripe/stripe-node).

### Instalar a biblioteca Ruby da Stripe

Instale o gem do Ruby da Stripe e exija-o no seu código. Alternativamente, se estiver começando do zero e precisar de um Gemfile, baixe os arquivos do projeto usando o link de download no editor de código.

#### Terminal

Instale o gem:

```bash
gem install stripe
```

#### Bundler

Adicione esta linha ao seu Gemfile:

```bash
gem 'stripe'
```

#### GitHub

Ou baixe o código-fonte do gem stripe-ruby diretamente [do GitHub](https://github.com/stripe/stripe-ruby).

### Instalar a biblioteca Java da Stripe

Adicione a dependência à compilação e importe a biblioteca. Se você estiver começando do zero e precisar de um modelo de arquivo pom.xml (para Maven), baixe os arquivos do projeto usando o link de download no editor de código.

#### Maven

Adicione a dependência a seguir ao POM e substitua {VERSION} pelo número de versão que você quer usar.

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

#### Gradle

Adicione a dependência ao arquivo build.gradle e substitua {VERSION} pelo número de versão que você quer usar.

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

#### GitHub

Baixe o JAR diretamente [do GitHub](https://github.com/stripe/stripe-java/releases/latest).

### Instalar o pacote Python da Stripe

Instale o pacote da Stripe e importe-o no seu código. Se você estiver começando do zero e precisar de um arquivo requirements.txt, baixe os arquivos do projeto usando o link de download no editor de código.

#### pip

Instale o pacote usando pip:

```bash
pip3 install stripe
```

#### GitHub

Faça o download diretamente o código-fonte da biblioteca Stripe-Python [do GitHub](https://github.com/stripe/stripe-python).

### Instalar a biblioteca PHP da Stripe

Instale a biblioteca com o composer e inicialize-a com sua chave de API secreta. Se você estiver começando do zero e precisar de um arquivo composer.json, baixe os arquivos usando o link de download no editor de código.

#### Composer

Instale a biblioteca:

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

#### GitHub

Ou baixe o código-fonte da biblioteca stripe-php diretamente [do GitHub](https://github.com/stripe/stripe-php).

### Configurar o servidor

Adicione a dependência à compilação e importe a biblioteca. Se você estiver começando do zero e precisar de um arquivo go.mod, baixe os arquivos do projeto usando o link de download no editor de código.

#### Go

Não se esqueça de inicializar com Go Modules:

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

#### GitHub

Ou baixe o código-fonte do módulo stripe-go diretamente [do GitHub](https://github.com/stripe/stripe-go).

### Instalar a biblioteca Stripe.net

Instale o pacote como .NET ou NuGet. Se estiver começando do zero, você também pode baixar os arquivos com um .csproj configurado.

#### dotnet

Instale a biblioteca:

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

#### NuGet

Instale a biblioteca:

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

#### GitHub

Ou baixe o código-fonte da biblioteca Stripe.net diretamente [do GitHub](https://github.com/stripe/stripe-dotnet).

### Instalar as bibliotecas da Stripe

Instale os pacotes e importe-os para o código. Se estiver começando do zero e precisar de um arquivo `package.json`, baixe os arquivos do projeto pelo link de download no editor de código.

Instale as bibliotecas:

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

### Criar uma sessão do Checkout

A [Checkout Session](https://docs.stripe.com/api/checkout/sessions.md) controla o que o seu cliente vê na página de pagamentos hospedada pela Stripe, como itens de linha, valor, moeda e formas de pagamento aceitas.

### Obter o preço com a chave de pesquisa

Passe a chave de pesquisa definida para o produto no endpoint [Price](https://docs.stripe.com/api/prices/list.md) para aplicar o preço ao pedido.

### Definir os itens de linha

Mantenha sempre no servidor os dados confidenciais do inventário de produtos, como preço e disponibilidade, para evitar manipulações no lado do cliente. Passe o ID do preço predefinido recuperado acima.

### Definir o modo

Defina o modo como `subscription`. O Checkout também aceita os modos [pagamento](https://docs.stripe.com/checkout/quickstart.md) e [configuração](https://docs.stripe.com/payments/save-and-reuse.md) para pagamentos não recorrentes.

### Fornecer URL de sucesso

Informe um URL acessível publicamente para onde a Stripe possa redirecionar os clientes após a conclusão. Acrescente o parâmetro de consulta `session_id` ao final do URL, pois isso permite recuperar o cliente depois e possibilita que a Stripe gere o Dashboard hospedado do cliente.

### Redirecionar do Checkout

Depois de criar a sessão, redirecione o cliente ao URL de sucesso ou cancelamento retornado na resposta.

### Criar uma sessão no portal de clientes

Inicie uma [sessão segura no portal de clientes](https://docs.stripe.com/api/customer_portal/sessions/create.md) hospedada pela Stripe que permita que os clientes gerenciem suas assinaturas e dados de cobrança.

### Redirecionar ao portal de clientes

Depois de criar a sessão do portal, redirecione o cliente ao URL retornado na resposta.

### Executar a assinatura

Crie um endpoint `/webhook` e obtenha sua chave secreta de webhook na guia [Webhooks](https://dashboard.stripe.com/webhooks) no Workbench para escutar eventos relacionados à atividade de assinatura. Após um pagamento bem-sucedido e redirecionamento para a página de finalização, verifique se o status da assinatura é `active` e conceda ao cliente acesso aos produtos e recursos assinados.

### Executar o servidor

Defina a variável de ambiente `STRIPE_WEBHOOK_SECRET` com o segredo de assinatura do seu webhook. Você encontra esse segredo na guia [Webhooks](https://dashboard.stripe.com/webhooks) do Workbench.

Inicie seu servidor e vá para <http://localhost:4242/>

```bash
npm start
```

### Executar o servidor

Defina a variável de ambiente `STRIPE_WEBHOOK_SECRET` com o segredo de assinatura do seu webhook. Você encontra esse segredo na guia [Webhooks](https://dashboard.stripe.com/webhooks) do Workbench.

Inicie o servidor. Uma janela de navegador é aberta automaticamente em <http://localhost:3000/checkout>

```bash
npm start
```

### Executar o servidor

Defina a variável de ambiente `STRIPE_WEBHOOK_SECRET` com o segredo de assinatura do seu webhook. Você encontra esse segredo na guia [Webhooks](https://dashboard.stripe.com/webhooks) do Workbench.

Inicie seu servidor e vá para <http://localhost:4242/>

```bash
ruby server.rb
```

### Executar o servidor

Defina a variável de ambiente `STRIPE_WEBHOOK_SECRET` com o segredo de assinatura do seu webhook. Você encontra esse segredo na guia [Webhooks](https://dashboard.stripe.com/webhooks) do Workbench.

Inicie o servidor. Uma janela de navegador é aberta automaticamente em <http://localhost:3000/checkout>

```bash
ruby server.rb
```

### Executar o servidor

Defina a variável de ambiente `STRIPE_WEBHOOK_SECRET` com o segredo de assinatura do seu webhook. Você encontra esse segredo na guia [Webhooks](https://dashboard.stripe.com/webhooks) do Workbench.

Inicie seu servidor e vá para <http://localhost:4242/>

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

### Executar o servidor

Defina a variável de ambiente `STRIPE_WEBHOOK_SECRET` com o segredo de assinatura do seu webhook. Você encontra esse segredo na guia [Webhooks](https://dashboard.stripe.com/webhooks) do Workbench.

Inicie o servidor. Uma janela de navegador é aberta automaticamente em <http://localhost:3000/checkout>

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

### Executar o servidor

Defina a variável de ambiente `STRIPE_WEBHOOK_SECRET` com o segredo de assinatura do seu webhook. Você encontra esse segredo na guia [Webhooks](https://dashboard.stripe.com/webhooks) do Workbench.

Inicie seu servidor e vá para <http://localhost:4242/>

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

### Executar o servidor

Defina a variável de ambiente `STRIPE_WEBHOOK_SECRET` com o segredo de assinatura do seu webhook. Você encontra esse segredo na guia [Webhooks](https://dashboard.stripe.com/webhooks) do Workbench.

Inicie o servidor. Uma janela de navegador é aberta automaticamente em <http://localhost:3000/checkout>

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

### Executar o servidor

Defina a variável de ambiente `STRIPE_WEBHOOK_SECRET` com o segredo de assinatura do seu webhook. Você encontra esse segredo na guia [Webhooks](https://dashboard.stripe.com/webhooks) do Workbench.

Inicie seu servidor e vá para <http://localhost:4242/>

```bash
dotnet run
```

### Executar o servidor

Defina a variável de ambiente `STRIPE_WEBHOOK_SECRET` com o segredo de assinatura do seu webhook. Você encontra esse segredo na guia [Webhooks](https://dashboard.stripe.com/webhooks) do Workbench.

Inicie o servidor. Uma janela de navegador é aberta automaticamente em <http://localhost:3000/checkout>

```bash
dotnet run
```

### Executar o servidor

Defina a variável de ambiente `STRIPE_WEBHOOK_SECRET` com o segredo de assinatura do seu webhook. Você encontra esse segredo na guia [Webhooks](https://dashboard.stripe.com/webhooks) do Workbench.

Inicie seu servidor e vá para <http://localhost:4242/>

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

### Executar o servidor

Defina a variável de ambiente `STRIPE_WEBHOOK_SECRET` com o segredo de assinatura do seu webhook. Você encontra esse segredo na guia [Webhooks](https://dashboard.stripe.com/webhooks) do Workbench.

Inicie o servidor. Uma janela de navegador é aberta automaticamente em <http://localhost:3000/checkout>

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

### Executar o servidor

Defina a variável de ambiente `STRIPE_WEBHOOK_SECRET` com o segredo de assinatura do seu webhook. Você encontra esse segredo na guia [Webhooks](https://dashboard.stripe.com/webhooks) do Workbench.

Inicie seu servidor e vá para <http://localhost:4242/>

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

### Executar o servidor

Defina a variável de ambiente `STRIPE_WEBHOOK_SECRET` com o segredo de assinatura do seu webhook. Você encontra esse segredo na guia [Webhooks](https://dashboard.stripe.com/webhooks) do Workbench.

Inicie o servidor. Uma janela de navegador é aberta automaticamente em <http://localhost:3000/checkout>

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

### Experimente

Clique no botão de checkout. Na página de pagamentos hospedada pela Stripe, use qualquer um desses cartões de teste para simular um pagamento.

| Scenario | Card Number |
| --- | --- |
| Payment succeeds | 4242424242424242 |
| Payment requires 3DS authentication | 4000002500003155 |
| Payment is declined | 4000000000009995 |

## Adicione recursos de personalização

Se você assinou o produto no teste, então você tem uma integração básica de checkout com assinaturas funcionando. Use as alternâncias abaixo para ver como personalizar este exemplo com recursos adicionais.

### Adicionar avaliações

Vincule um período de avaliação a uma sessão do Checkout.

### Adicionar um período de avaliação

Use `subscription_data` para adicionar um inteiro que representa o número de `trial_period_days` antes de cobrar o cliente pela primeira vez. Deve ser pelo menos `1`.

Se você iniciar um período de teste gratuito sem uma forma de pagamento, defina o campo `trial_settings[end_behavior][missing_payment_method]` como `pause (suspender)` ou `cancel (cancelar)` para que a assinatura não continue caso o período de teste termine sem uma forma de pagamento. Passe esse parâmetro em `subscription_data` ao criar uma sessão de Checkout ou atualize-o na assinatura em outro momento. Consulte [Use trial periods](https://docs.stripe.com/billing/subscriptions/trials/free-trials.md#create-free-trials-without-payment) para mais informações.

### Definir data do ciclo de faturamento

Especifique uma âncora do ciclo de faturamento quando criar uma sessão do Checkout.

### Anexe o ciclo de faturamento da assinatura

Use `subscription_data` para definir um carimbo de data e hora `billing_cycle_anchor` para a próxima data de cobrança da assinatura. Consulte [Definir data do ciclo de cobrança no Checkout](https://docs.stripe.com/payments/checkout/billing-cycle.md) para obter mais informações.

### Automatizar o recolhimento de impostos

Calcule e recolha o valor correto de impostos sobre suas transações da Stripe. Antes da integração, saiba mais sobre o [Stripe Tax](https://docs.stripe.com/tax.md) e [como adicioná-lo ao Checkout](https://docs.stripe.com/tax/checkout.md). [Ative o Stripe Tax](https://dashboard.stripe.com/tax) no Dashboard antes da integração.

### Adicionar o parâmetro de imposto automático

Defina o parâmetro `automatic_tax` como `enabled: true`.

    <script src="https://js.stripe.com/endive/stripe.js"></script>
      <div class="product">
        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="16px" viewBox="0 0 14 16" version="1.1">
            <defs/>
            <g id="Flow" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
                <g id="0-Default" transform="translate(-121.000000, -40.000000)" fill="#E184DF">
                    <path d="M127,50 L126,50 C123.238576,50 121,47.7614237 121,45 C121,42.2385763 123.238576,40 126,40 L135,40 L135,56 L133,56 L133,42 L129,42 L129,56 L127,56 L127,50 Z M127,48 L127,42 L126,42 C124.343146,42 123,43.3431458 123,45 C123,46.6568542 124.343146,48 126,48 L127,48 Z" id="Pilcrow"/>
                </g>
            </g>
        </svg>
        <div class="description">
          <h3>{{PRODUCT_NAME}}</h3>
          <h5>{{FORMATTED_RECURRING_PRICE}}</h5>
        </div>
      </div>
      <form action="/create-checkout-session" method="POST">
        <!-- Add a hidden field with the lookup_key of your Price -->
        <input type="hidden" name="lookup_key" value="{{PRICE_LOOKUP_KEY}}" />
        <button id="checkout-and-portal-button" type="submit">Checkout</button>
      </form>
      <form action="/create-checkout-session.php" method="POST">
        <!-- Add a hidden field with the lookup_key of your Price -->
        <input type="hidden" name="lookup_key" value="{{PRICE_LOOKUP_KEY}}" />
        <button id="checkout-and-portal-button" type="submit">Checkout</button>
      </form>
<body>
  <section>
    <div class="product Box-root">
      <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="16px" viewBox="0 0 14 16" version="1.1">
          <defs/>
          <g id="Flow" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
              <g id="0-Default" transform="translate(-121.000000, -40.000000)" fill="#E184DF">
                  <path d="M127,50 L126,50 C123.238576,50 121,47.7614237 121,45 C121,42.2385763 123.238576,40 126,40 L135,40 L135,56 L133,56 L133,42 L129,42 L129,56 L127,56 L127,50 Z M127,48 L127,42 L126,42 C124.343146,42 123,43.3431458 123,45 C123,46.6568542 124.343146,48 126,48 L127,48 Z" id="Pilcrow"/>
              </g>
          </g>
      </svg>
      <div class="description Box-root">
        <h3>Subscription to {{PRODUCT_NAME}} successful!</h3>
      </div>
    </div>
    <form action="/create-portal-session" method="POST">
      <input type="hidden" id="session-id" name="session_id" value="" />
      <button id="checkout-and-portal-button" type="submit">Manage your billing information</button>
    </form>
    <form action="/create-portal-session.php" method="POST">
      <input type="hidden" id="session-id" name="session_id" value="" />
      <button id="checkout-and-portal-button" type="submit">Manage your billing information</button>
    </form>
  </section>
</body>
<body>
  <section>
    <p>Picked the wrong subscription? Shop around then come back to pay!</p>
  </section>
</body>
    <div className="product">
      <Logo />
      <div className="description">
        <h3>{{PRODUCT_NAME}}</h3>
        <h5>{{FORMATTED_RECURRING_PRICE}}</h5>
      </div>
    </div>
    <form action="/create-checkout-session" method="POST">
      {/* Add a hidden field with the lookup_key of your Price */}
      <input type="hidden" name="lookup_key" value="{{PRICE_LOOKUP_KEY}}" />
      <button id="checkout-and-portal-button" type="submit">
        Checkout
      </button>
    </form>
    <form action="/create-checkout-session.php" method="POST">
      {/* Add a hidden field with the lookup_key of your Price */}
      <input type="hidden" name="lookup_key" value="{{PRICE_LOOKUP_KEY}}" />
      <button id="checkout-and-portal-button" type="submit">
        Checkout
      </button>
    </form>
    <section>
      <div className="product Box-root">
        <Logo />
        <div className="description Box-root">
          <h3>Subscription to {{PRODUCT_NAME}} successful!</h3>
        </div>
      </div>
      <form action="/create-portal-session" method="POST">
        <input
          type="hidden"
          id="session-id"
          name="session_id"
          value={sessionId}
        />
        <button id="checkout-and-portal-button" type="submit">
          Manage your billing information
        </button>
      </form>
      <form action="/create-portal-session.php" method="POST">
        <input
          type="hidden"
          id="session-id"
          name="session_id"
          value={sessionId}
        />
        <button id="checkout-and-portal-button" type="submit">
          Manage your billing information
        </button>
      </form>
    </section>
{
  "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": "^5.0.1",
    "stripe": "^8.202.0"
  },
  "devDependencies": {
    "concurrently": "4.1.2"
  },
  "homepage": "http://localhost:3000/checkout",
  "proxy": "http://127.0.0.1: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-scripts": "^5.0.1"
  },
  "homepage": "http://localhost:3000/checkout",
  "proxy": "http://127.0.0.1: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"
    ]
  }
}
// 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 YOUR_DOMAIN = "http://localhost:4242";
const YOUR_DOMAIN = "http://localhost:3000";
  const prices = await stripe.prices.list({
    lookup_keys: [req.body.lookup_key],
    expand: ['data.product'],
  });
  const session = await stripe.checkout.sessions.create({
    billing_address_collection: 'auto',
    line_items: [
      {
        price: prices.data[0].id,
        // For usage-based billing, don't pass quantity
        quantity: 1,

      },
    ],
    mode: 'subscription',
    success_url: `${YOUR_DOMAIN}/success.html?session_id={CHECKOUT_SESSION_ID}`,
    success_url: `${YOUR_DOMAIN}/?success=true&session_id={CHECKOUT_SESSION_ID}`,
    discounts: [{
      coupon: '{{COUPON_ID}}',
    }],
    customer: 'cus_123',
    customer_account: 'acct_123',
    subscription_data: {
      trial_period_days: 7,
      billing_cycle_anchor: 1672531200,
    },
    subscription_data: {
      billing_cycle_anchor: 1672531200,
    },
    automatic_tax: { enabled: true },
  });

  res.redirect(303, session.url);
  // This is the url to which the customer will be redirected when they're done
  // managing their billing with the portal.
  const returnUrl = YOUR_DOMAIN;

  const portalSession = await stripe.billingPortal.sessions.create({
    customer: checkoutSession.customer,
    return_url: returnUrl,
  });
  // This is the url to which the customer will be redirected when they're done
  // managing their billing with the portal.
  const returnUrl = YOUR_DOMAIN;

  const portalSession = await stripe.billingPortal.sessions.create({
    customer_account: checkoutSession.customer_account,
    return_url: returnUrl,
  });
  res.redirect(303, portalSession.url);
app.post(
  '/webhook',
  express.raw({ type: 'application/json' }),
  (request, response) => {
    let event = request.body;

    // To run this example, set an environment variable STRIPE_WEBHOOK_SECRET to
    // your endpoint's unique secret.
    //
    // If you are testing with the CLI, find the secret by running 'stripe listen'.
    // If you are using an endpoint defined with the API or dashboard, look in
    // your webhook settings at https://dashboard.stripe.com/webhooks.
    //
    // Don't include webhook secrets in code.
    const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;

    // Only verify the event if you have an endpoint secret defined.
    // Otherwise use the basic event deserialized with JSON.parse
    if (endpointSecret) {
      // Get the signature sent by Stripe
      const signature = request.headers['stripe-signature'];
      try {
        event = stripe.webhooks.constructEvent(
          request.body,
          signature,
          endpointSecret
        );
      } catch (err) {
        console.log(`⚠️  Webhook signature verification failed.`, err.message);
        return response.sendStatus(400);
      }
    }
    let subscription;
    let status;
    // Handle the event
    switch (event.type) {
      case 'customer.subscription.trial_will_end':
        subscription = event.data.object;
        status = subscription.status;
        console.log(`Subscription status is ${status}.`);
        // Then define and call a method to handle the subscription trial ending.
        // handleSubscriptionTrialEnding(subscription);
        break;
      case 'customer.subscription.deleted':
        subscription = event.data.object;
        status = subscription.status;
        console.log(`Subscription status is ${status}.`);
        // Then define and call a method to handle the subscription deleted.
        // handleSubscriptionDeleted(subscriptionDeleted);
        break;
      case 'customer.subscription.created':
        subscription = event.data.object;
        status = subscription.status;
        console.log(`Subscription status is ${status}.`);
        // Then define and call a method to handle the subscription created.
        // handleSubscriptionCreated(subscription);
        break;
      case 'customer.subscription.updated':
        subscription = event.data.object;
        status = subscription.status;
        console.log(`Subscription status is ${status}.`);
        // Then define and call a method to handle the subscription update.
        // handleSubscriptionUpdated(subscription);
        break;
      case 'entitlements.active_entitlement_summary.updated':
        subscription = event.data.object;
        console.log(`Active entitlement summary updated for ${subscription}.`);
        // Then define and call a method to handle active entitlement summary updated
        // handleEntitlementUpdated(subscription);
        break;
      default:
        // Unexpected event type
        console.log(`Unhandled event type ${event.type}.`);
    }
    // Return a 200 response to acknowledge receipt of the event
    response.send();
  }
);
{
  "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": "^22.6.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": "^5.0.1",
    "stripe": "22.6.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"
    ]
  }
}
\# 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>>')
  prices = client.v1.prices.list(
    lookup_keys: [params['lookup_key']],
    expand: ['data.product']
  )
    session = client.v1.checkout.sessions.create({
      mode: 'subscription',
      line_items: [{
        quantity: 1,
        price: prices.data[0].id
      }],
      success_url: YOUR_DOMAIN + '/success.html?session_id={CHECKOUT_SESSION_ID}',
      success_url: YOUR_DOMAIN + '?success=true&session_id={CHECKOUT_SESSION_ID}',
      subscription_data: {
        trial_period_days: 7,
        billing_cycle_anchor: 1672531200
      },
      subscription_data: {
        billing_cycle_anchor: 1672531200
      },
      customer: 'cus_JyTTNqVDAoRYE1',
      customer_account: 'acct_123',
      discounts: [{
        coupon: 'gBY6sFUf'
      }],
      automatic_tax: {
        enabled: true
      },
    })
  redirect session.url, 303
  session = client.v1.billing_portal.sessions.create({

                                                    customer: checkout_session.customer,
                                                    return_url: return_url
                                                  })
  session = client.v1.billing_portal.sessions.create({

                                                    customer_account: checkout_session.customer_account,
                                                    return_url: return_url
                                                  })
  redirect session.url, 303
post '/webhook' do
  \# To run this example, set an environment variable STRIPE_WEBHOOK_SECRET to
  # your endpoint's unique secret.
  #
  # If you are testing with the CLI, find the secret by running 'stripe listen'.
  # If you are using an endpoint defined with the API or dashboard, look in
  # your webhook settings at https://dashboard.stripe.com/webhooks.
  #
  # Don't include webhook secrets in code.
  webhook_secret = ENV['STRIPE_WEBHOOK_SECRET']

  payload = request.body.read
  if webhook_secret
    # Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured.
    sig_header = request.env['HTTP_STRIPE_SIGNATURE']
    event = nil

    begin
      event = Stripe::Webhook.construct_event(
        payload, sig_header, webhook_secret
      )
    rescue JSON::ParserError => e
      # Invalid payload
      status 400
      return
    rescue Stripe::SignatureVerificationError => e
      # Invalid signature
      puts '⚠️  Webhook signature verification failed.'
      status 400
      return
    end
  else
    data = JSON.parse(payload, symbolize_names: true)
    event = Stripe::Event.construct_from(data)
  end
  # Get the type of webhook event sent - used to check the status of PaymentIntents.
  event_type = event['type']
  data = event['data']
  data_object = data['object']

  if event.type == 'customer.subscription.deleted'
    # handle subscription canceled automatically based
    # upon your subscription settings. Or if the user cancels it.
    # puts data_object
    puts "Subscription canceled: #{event.id}"
  end

  if event.type == 'customer.subscription.updated'
    # handle subscription updated
    # puts data_object
    puts "Subscription updated: #{event.id}"
  end

  if event.type == 'customer.subscription.created'
    # handle subscription created
    # puts data_object
    puts "Subscription created: #{event.id}"
  end

  if event.type == 'customer.subscription.trial_will_end'
    # handle subscription trial ending
    # puts data_object
    puts "Subscription trial will end: #{event.id}"
  end

  if event.type == 'entitlements.active_entitlement_summary.updated'
    # handle active entitlement summary updated
    # puts data_object
    puts "Active entitlement summary updated: #{event.id}"
  end

  content_type 'application/json'
  {
    status: 'success'
  }.to_json
end
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>>')
    try:
        prices = client.v1.prices.list(params={
            'lookup_keys': [request.form['lookup_key']],
            'expand': ['data.product'],
        })

        checkout_session = client.v1.checkout.sessions.create(params={
            'line_items': [
                {
                    'price': prices.data[0].id,
                    'quantity': 1,
                },
            ],
            'mode': 'subscription',
            'success_url': YOUR_DOMAIN +
            '/success.html?session_id={CHECKOUT_SESSION_ID}',
            'success_url': YOUR_DOMAIN +
            '?success=true&session_id={CHECKOUT_SESSION_ID}',
            'subscription_data': {
                'trial_period_days': 7,
                'billing_cycle_anchor': 1672531200,
            },
            'subscription_data': {
                'billing_cycle_anchor': 1672531200,
            },
            'discounts': [
                {
                    'coupon': '{{COUPON_ID}}'
                }
            ],
            'customer': 'cus_123',
            'customer_account': 'acct_123',
            'automatic_tax': {
              'enabled': True
            },
        })
        return redirect(checkout_session.url, code=303)
    portalSession = client.v1.billing_portal.sessions.create(params={
        'customer': checkout_session.customer,
        'return_url': return_url,
    })
    portalSession = client.v1.billing_portal.sessions.create(params={
        'customer_account': checkout_session.customer_account,
        'return_url': return_url,
    })
    return redirect(portalSession.url, code=303)
@app.route('/webhook', methods=['POST'])
def webhook_received():
    \# To run this example, set an environment variable STRIPE_WEBHOOK_SECRET to
    # your endpoint's unique secret.
    #
    # If you are testing with the CLI, find the secret by running 'stripe listen'.
    # If you are using an endpoint defined with the API or dashboard, look in
    # your webhook settings at https://dashboard.stripe.com/webhooks.
    #
    # Don't include webhook secrets in code.
    webhook_secret = os.environ.get('STRIPE_WEBHOOK_SECRET')

    request_data = json.loads(request.data)

    if webhook_secret:
        # Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured.
        signature = request.headers.get('stripe-signature')
        try:
            event = client.construct_event(
                payload=request.data, sig_header=signature, secret=webhook_secret)
            data = event['data']
        except Exception as e:
            return e
        # Get the type of webhook event sent - used to check the status of PaymentIntents.
        event_type = event['type']
    else:
        data = request_data['data']
        event_type = request_data['type']
    data_object = data['object']

    print('event ' + event_type)

    if event_type == 'checkout.session.completed':
        print('🔔 Payment succeeded!')
    elif event_type == 'customer.subscription.trial_will_end':
        print('Subscription trial will end')
    elif event_type == 'customer.subscription.created':
        print('Subscription created %s', event.id)
    elif event_type == 'customer.subscription.updated':
        print('Subscription created %s', event.id)
    elif event_type == 'customer.subscription.deleted':
        # handle subscription canceled automatically based
        # upon your subscription settings. Or if the user cancels it.
        print('Subscription canceled: %s', event.id)
    elif event_type == 'entitlements.active_entitlement_summary.updated':
        # handle active entitlement summary updated
        print('Active entitlement summary updated: %s', event.id)

    return jsonify({'status': 'success'})
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==15.6.0
toml==0.10.2
Werkzeug==3.1.5
  $session = $stripe->billingPortal->sessions->create([
    'customer' => $checkout_session->customer,
    'return_url' => $return_url,
  ]);
  $session = $stripe->billingPortal->sessions->create([
    'customer_account' => $checkout_session->customer_account,
    'return_url' => $return_url,
  ]);
  header("HTTP/1.1 303 See Other");
  header("Location: " . $session->url);

// To run this example, set an environment variable STRIPE_WEBHOOK_SECRET to
// your endpoint's unique secret.
//
// If you are testing with the CLI, find the secret by running 'stripe listen'.
// If you are using an endpoint defined with the API or dashboard, look in
// your webhook settings at https://dashboard.stripe.com/webhooks.
//
// Don't include webhook secrets in code.
$endpoint_secret = getenv('STRIPE_WEBHOOK_SECRET');

$payload = @file_get_contents('php://input');
$event = null;
try {
  $event = \Stripe\Event::constructFrom(
    json_decode($payload, true)
  );
} catch(\UnexpectedValueException $e) {
  // Invalid payload
  echo '⚠️  Webhook error while parsing basic request.';
  http_response_code(400);
  exit();
}
// Handle the event
switch ($event->type) {
  case 'customer.subscription.trial_will_end':
    $subscription = $event->data->object; // contains a \Stripe\Subscription
    // Then define and call a method to handle the trial ending.
    // handleTrialWillEnd($subscription);
    break;
  case 'customer.subscription.created':
    $subscription = $event->data->object; // contains a \Stripe\Subscription
    // Then define and call a method to handle the subscription being created.
    // handleSubscriptionCreated($subscription);
    break;
  case 'customer.subscription.deleted':
    $subscription = $event->data->object; // contains a \Stripe\Subscription
    // Then define and call a method to handle the subscription being deleted.
    // handleSubscriptionDeleted($subscription);
    break;
  case 'customer.subscription.updated':
    $subscription = $event->data->object; // contains a \Stripe\Subscription
    // Then define and call a method to handle the subscription being updated.
    // handleSubscriptionUpdated($subscription);
    break;
  case 'entitlements.active_entitlement_summary.updated':
    $subscription = $event->data->object; // contains a \Stripe\Subscription
    // Then define and call a method to handle active entitlement summary updated.
    // handleEntitlementUpdated($subscription);
    break;
  default:
    // Unexpected event type
    echo 'Received unknown event type';
}
// Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
$stripeSecretKey = '<<YOUR_SECRET_KEY>>';
$stripe = new \Stripe\StripeClient($stripeSecretKey);
  $prices = $stripe->prices->all([
    // retrieve lookup_key from form data POST body
    'lookup_keys' => [$_POST['lookup_key']],
    'expand' => ['data.product']
  ]);
  $checkout_session = $stripe->checkout->sessions->create([
    'line_items' => [[
      'price' => $prices->data[0]->id,
      'quantity' => 1,
    ]],
    'mode' => 'subscription',
    'success_url' => $YOUR_DOMAIN . '/success.html?session_id={CHECKOUT_SESSION_ID}',
    'success_url' => $YOUR_DOMAIN . '?success=true&session_id={CHECKOUT_SESSION_ID}',
    'subscription_data' => [
      'trial_period_days' => 7,
      'billing_cycle_anchor' => 1672531200,
    ],
    'subscription_data' => [
      'billing_cycle_anchor' => 1672531200,
    ],
    'discounts' => [[
        'coupon' => '{{COUPON_ID}}',
    ]],
    'customer' => 'cus_123',
    'automatic_tax' => [
      'enabled' => true,
    ],
  ]);
  header("HTTP/1.1 303 See Other");
  header("Location: " . $checkout_session->url);
            // 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>>"));
            var priceOptions = new PriceListOptions
            {
                LookupKeys = new List<string> {
                    Request.Form["lookup_key"]
                }
            };
            StripeList<Price> prices = _client.V1.Prices.List(priceOptions);
            var options = new SessionCreateOptions
            {
                LineItems = new List<SessionLineItemOptions>
                {
                  new SessionLineItemOptions
                  {
                    Price = prices.Data[0].Id,
                    Quantity = 1,
                  },
                },
                Mode = "subscription",
                SuccessUrl = domain + "/success.html?session_id={CHECKOUT_SESSION_ID}",
                SuccessUrl = domain + "?success=true&session_id={CHECKOUT_SESSION_ID}",
                SubscriptionData = new SessionSubscriptionDataOptions
                {
                    TrialPeriodDays = 7,
                    BillingCycleAnchor = 1672531200,
                },
                SubscriptionData = new SessionSubscriptionDataOptions
                {
                    BillingCycleAnchor = 1672531200,
                },
                Customer = "cus_123",
      CustomerAccount: stripe.String("acct_123"),
                AutomaticTax = new SessionAutomaticTaxOptions { Enabled = true },
                CustomerAccount = "acct_123",
            };
            Session session = _client.V1.Checkout.Sessions.Create(options);
            Response.Headers.Add("Location", session.Url);
            return new StatusCodeResult(303);
            var options = new Stripe.BillingPortal.SessionCreateOptions
            {
                Customer = checkoutSession.CustomerId,
                ReturnUrl = returnUrl,
            };
            var session = _client.V1.BillingPortal.Sessions.Create(options);
            var options = new Stripe.BillingPortal.SessionCreateOptions
            {
                CustomerAccount = checkoutSession.CustomerAccount,
                ReturnUrl = returnUrl,
            };
            var session = _client.V1.BillingPortal.Sessions.Create(options);
            Response.Headers.Add("Location", session.Url);
            return new StatusCodeResult(303);
    [Route("webhook")]
    [ApiController]
    public class WebhookController : Controller
    {
        [HttpPost]
        public async Task<IActionResult> Index()
        {
            // To run this example, set an environment variable STRIPE_WEBHOOK_SECRET to
            // your endpoint's unique secret.
            //
            // If you are testing with the CLI, find the secret by running 'stripe listen'.
            // If you are using an endpoint defined with the API or dashboard, look in
            // your webhook settings at https://dashboard.stripe.com/webhooks.
            //
            // Don't include webhook secrets in code.
            var endpointSecret = Environment.GetEnvironmentVariable("STRIPE_WEBHOOK_SECRET");

            var json = await new StreamReader(HttpContext.Request.Body).ReadToEndAsync();

            try
            {
                var stripeEvent = EventUtility.ParseEvent(json);
                var signatureHeader = Request.Headers["Stripe-Signature"];
                stripeEvent = EventUtility.ConstructEvent(json,
                        signatureHeader, endpointSecret);
                // If on SDK version < 46, use class Events instead of EventTypes
                if (stripeEvent.Type == EventTypes.CustomerSubscriptionDeleted)
                {
                    var subscription = stripeEvent.Data.Object as Subscription;
                    Console.WriteLine("A subscription was canceled.", subscription.Id);
                    // Then define and call a method to handle the successful payment intent.
                    // handleSubscriptionCanceled(subscription);
                }
                else if (stripeEvent.Type == EventTypes.CustomerSubscriptionUpdated)
                {
                    var subscription = stripeEvent.Data.Object as Subscription;
                    Console.WriteLine("A subscription was updated.", subscription.Id);
                    // Then define and call a method to handle the successful payment intent.
                    // handleSubscriptionUpdated(subscription);
                }
                else if (stripeEvent.Type == EventTypes.CustomerSubscriptionCreated)
                {
                    var subscription = stripeEvent.Data.Object as Subscription;
                    Console.WriteLine("A subscription was created.", subscription.Id);
                    // Then define and call a method to handle the successful payment intent.
                    // handleSubscriptionUpdated(subscription);
                }
                else if (stripeEvent.Type == EventTypes.CustomerSubscriptionTrialWillEnd)
                {
                    var subscription = stripeEvent.Data.Object as Subscription;
                    Console.WriteLine("A subscription trial will end", subscription.Id);
                    // Then define and call a method to handle the successful payment intent.
                    // handleSubscriptionUpdated(subscription);
                }
                else if (stripeEvent.Type == EventTypes.ActiveEntitlementSummaryUpdated)
                {
                    var summary = stripeEvent.Data.Object as ActiveEntitlementSummary;
                    Console.WriteLine("Active entitlement summary updated for customer", summary.Customer);
                    // Then define and call a method to handle active entitlement summary updated.
                    // handleEntitlementUpdated($subscription);
                }
                else
                {
                    Console.WriteLine("Unhandled event type: {0}", stripeEvent.Type);
                }
                return Ok();
            }
            catch (StripeException e)
            {
                Console.WriteLine("Error: {0}", e.Message);
                return BadRequest();
            }
        }
    "github.com/stripe/stripe-go/v86"
    "github.com/stripe/stripe-go/v86/webhook"
    // 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>>")
    params := &stripe.PriceListParams{
      LookupKeys: stripe.StringSlice([]string{
        lookup_key,
      }),
    }
    var price *stripe.Price
    for p, err := range sc.V1Prices.List(context.TODO(), params).All(context.TODO()) {
      if err != nil {
        log.Printf("sc.V1Prices.List: %v", err)
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
      }
      price = p
      break
    }
    if price == nil {
      log.Printf(">>>>>>>>>>>>>>>>>>>>>>>>>>> Add a price lookup key to checkout.html for the demo <<<<<<<<<<<<<<<<<<<<<<<<")
      return
    }
    checkoutParams := &stripe.CheckoutSessionCreateParams{
      Mode: stripe.String(stripe.CheckoutSessionModeSubscription),
      LineItems: []*stripe.CheckoutSessionCreateLineItemParams{
        &stripe.CheckoutSessionCreateLineItemParams{
          Price:    stripe.String(price.ID),
          Quantity: stripe.Int64(1),
        },
      },
      SubscriptionData: &stripe.CheckoutSessionCreateSubscriptionDataParams{
        TrialPeriodDays: stripe.Int64(7),
        BillingCycleAnchor: stripe.Int64(1672531200),
      },
      SubscriptionData: &stripe.CheckoutSessionCreateSubscriptionDataParams{
        BillingCycleAnchor: stripe.Int64(1672531200),
      },
      Discounts: []*stripe.CheckoutSessionCreateDiscountParams{
        &stripe.CheckoutSessionCreateDiscountParams{
          Coupon: stripe.String("gBY6sFUf"),
        },
      },
      SuccessURL: stripe.String(domain + "/success.html?session_id={CHECKOUT_SESSION_ID}"),
      SuccessURL: stripe.String(domain + "?success=true&session_id={CHECKOUT_SESSION_ID}"),
      Customer: stripe.String("cus_123"),
      CustomerAccount: stripe.String("acct_123"),
      AutomaticTax: &stripe.CheckoutSessionCreateAutomaticTaxParams{
        Enabled: stripe.Bool(true),
      },
    }

    s, err := sc.V1CheckoutSessions.Create(context.TODO(), checkoutParams)
    http.Redirect(w, r, s.URL, http.StatusSeeOther)
    // Authenticate your user.
    params := &stripe.BillingPortalSessionCreateParams{
      Customer:  stripe.String(s.Customer.ID),
      ReturnURL: stripe.String(domain),
    }
    ps, _ := sc.V1BillingPortalSessions.Create(context.TODO(), params)
    log.Printf("sc.V1BillingPortalSessions.Create: %v", ps.URL)
    // Authenticate your user.
    params := &stripe.BillingPortalSessionCreateParams{
      CustomerAccount: stripe.String(s.CustomerAccount),
      ReturnURL: stripe.String(domain),
    }
    ps, _ := sc.V1BillingPortalSessions.Create(context.TODO(), params)
    log.Printf("sc.V1BillingPortalSessions.Create: %v", ps.URL)
    http.Redirect(w, r, ps.URL, http.StatusSeeOther)
func handleWebhook(w http.ResponseWriter, req *http.Request) {
    const MaxBodyBytes = int64(65536)
    bodyReader := http.MaxBytesReader(w, req.Body, MaxBodyBytes)
    payload, err := ioutil.ReadAll(bodyReader)
    if err != nil {
      fmt.Fprintf(os.Stderr, "Error reading request body: %v\n", err)
      w.WriteHeader(http.StatusServiceUnavailable)
      return
    }

    // To run this example, set an environment variable STRIPE_WEBHOOK_SECRET to
    // your endpoint's unique secret.
    //
    // If you are testing with the CLI, find the secret by running 'stripe listen'.
    // If you are using an endpoint defined with the API or dashboard, look in
    // your webhook settings at https://dashboard.stripe.com/webhooks.
    //
    // Don't include webhook secrets in code.
    endpointSecret := os.Getenv("STRIPE_WEBHOOK_SECRET")

    signatureHeader := req.Header.Get("Stripe-Signature")
    event, err := sc.ConstructEvent(payload, signatureHeader, endpointSecret)
    if err != nil {
      fmt.Fprintf(os.Stderr, "⚠️  Webhook signature verification failed. %v\n", err)
      w.WriteHeader(http.StatusBadRequest) // Return a 400 error on a bad signature
      return
    }
    // Unmarshal the event data into an appropriate struct depending on its Type
    switch event.Type {
    case "customer.subscription.deleted":
      var subscription stripe.Subscription
      err := json.Unmarshal(event.Data.Raw, &subscription)
      if err != nil {
        fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err)
        w.WriteHeader(http.StatusBadRequest)
        return
      }
      log.Printf("Subscription deleted for %d.", subscription.ID)
      // Then define and call a func to handle the deleted subscription.
      // handleSubscriptionCanceled(subscription)
    case "customer.subscription.updated":
      var subscription stripe.Subscription
      err := json.Unmarshal(event.Data.Raw, &subscription)
      if err != nil {
        fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err)
        w.WriteHeader(http.StatusBadRequest)
        return
      }
      log.Printf("Subscription updated for %d.", subscription.ID)
      // Then define and call a func to handle the successful attachment of a PaymentMethod.
      // handleSubscriptionUpdated(subscription)
    case "customer.subscription.created":
      var subscription stripe.Subscription
      err := json.Unmarshal(event.Data.Raw, &subscription)
      if err != nil {
        fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err)
        w.WriteHeader(http.StatusBadRequest)
        return
      }
      log.Printf("Subscription created for %d.", subscription.ID)
      // Then define and call a func to handle the successful attachment of a PaymentMethod.
      // handleSubscriptionCreated(subscription)
    case "customer.subscription.trial_will_end":
      var subscription stripe.Subscription
      err := json.Unmarshal(event.Data.Raw, &subscription)
      if err != nil {
        fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err)
        w.WriteHeader(http.StatusBadRequest)
        return
      }
      log.Printf("Subscription trial will end for %d.", subscription.ID)
      // Then define and call a func to handle the successful attachment of a PaymentMethod.
      // handleSubscriptionTrialWillEnd(subscription)
    case "entitlements.active_entitlement_summary.updated":
      var subscription stripe.Subscription
      err := json.Unmarshal(event.Data.Raw, &subscription)
      if err != nil {
        fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err)
        w.WriteHeader(http.StatusBadRequest)
        return
      }
      log.Printf("Active entitlement summary updated for %d.", subscription.ID)
      // Then define and call a func to handle active entitlement summary updated.
      // handleEntitlementUpdated(subscription)
    default:
      fmt.Fprintf(os.Stderr, "Unhandled event type: %s\n", event.Type)
    }
    w.WriteHeader(http.StatusOK)
  }
require github.com/stripe/stripe-go/v86 v86.4.0
    // 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.
    StripeClient client = new StripeClient("<<YOUR_SECRET_KEY>>");
      PriceListParams priceParams = PriceListParams.builder().addLookupKey(request.queryParams("lookup_key")).build();
      StripeCollection<Price> prices = client.v1().prices().list(priceParams);
      SessionCreateParams params = SessionCreateParams.builder()
          .addLineItem(
              SessionCreateParams.LineItem.builder().setPrice(prices.getData().get(0).getId()).setQuantity(1L).build())
          .setMode(SessionCreateParams.Mode.SUBSCRIPTION)
          .setSuccessUrl(YOUR_DOMAIN + "/success.html?session_id={CHECKOUT_SESSION_ID}")
          .setSuccessUrl(YOUR_DOMAIN + "?success=true&session_id={CHECKOUT_SESSION_ID}")
          .setSubscriptionData(SessionCreateParams.SubscriptionData.builder().setTrialPeriodDays(7L).setBillingCycleAnchor(1672531200).build())
          .setSubscriptionData(SessionCreateParams.SubscriptionData.builder().setBillingCycleAnchor(1672531200).build())
          .addDiscount(SessionCreateParams.Discount.builder().setCoupon("{{COUPON_ID}}").build())
          .setCustomer("cus_JyTTNqVDAoRYE1")
          .setCustomerAccount("acct_123")
          .setAutomaticTax(
            SessionCreateParams.AutomaticTax.builder()
              .setEnabled(true)
              .build())
          .build();
      Session session = client.v1().checkout().sessions().create(params);
      response.redirect(session.getUrl(), 303);
      com.stripe.param.billingportal.SessionCreateParams params = new com.stripe.param.billingportal.SessionCreateParams.Builder()
          .setCustomer(checkoutSession.getCustomer())
          .setReturnUrl(YOUR_DOMAIN).build();

      com.stripe.model.billingportal.Session portalSession = client.v1().billingPortal().sessions().create(params);

      com.stripe.param.billingportal.SessionCreateParams params = new com.stripe.param.billingportal.SessionCreateParams.Builder()
          .setCustomerAccount(checkoutSession.getCustomerAccount())
          .setReturnUrl(YOUR_DOMAIN).build();

      com.stripe.model.billingportal.Session portalSession = client.v1().billingPortal().sessions().create(params);

      response.redirect(portalSession.getUrl(), 303);
      return "";
    post("/webhook", (request, response) -> {
      String payload = request.body();
      Event event = null;
      try {
        event = ApiResource.GSON.fromJson(payload, Event.class);
      } catch (JsonSyntaxException e) {
        // Invalid payload
        System.out.println("⚠️  Webhook error while parsing basic request.");
        response.status(400);
        return "";
      }
      String sigHeader = request.headers("Stripe-Signature");
      if (endpointSecret != null && sigHeader != null) {
        // Only verify the event if you have an endpoint secret defined.
        // Otherwise use the basic event deserialized with GSON.
        try {
          event = client.constructEvent(payload, sigHeader, endpointSecret);
        } catch (SignatureVerificationException e) {
          // Invalid signature
          System.out.println("⚠️  Webhook error while validating signature.");
          response.status(400);
          return "";
        }
      }
      // Deserialize the nested object inside the event
      EventDataObjectDeserializer dataObjectDeserializer = event.getDataObjectDeserializer();
      StripeObject stripeObject = null;
      if (dataObjectDeserializer.getObject().isPresent()) {
        stripeObject = dataObjectDeserializer.getObject().get();
      } else {
        // Deserialization failed, probably due to an API version mismatch.
        // Refer to the Javadoc documentation on `EventDataObjectDeserializer` for
        // instructions on how to handle this case, or return an error here.
      }
      // Handle the event
      Subscription subscription = null;
      switch (event.getType()) {
        case "customer.subscription.deleted":
          subscription = (Subscription) stripeObject;
          // Then define and call a function to handle the event
          // customer.subscription.deleted
          // handleSubscriptionTrialEnding(subscription);
        case "customer.subscription.trial_will_end":
          subscription = (Subscription) stripeObject;
          // Then define and call a function to handle the event
          // customer.subscription.trial_will_end
          // handleSubscriptionDeleted(subscriptionDeleted);
        case "customer.subscription.created":
          subscription = (Subscription) stripeObject;
          // Then define and call a function to handle the event
          // customer.subscription.created
          // handleSubscriptionCreated(subscription);
        case "customer.subscription.updated":
          subscription = (Subscription) stripeObject;
          // Then define and call a function to handle the event
          // customer.subscription.updated
          // handleSubscriptionUpdated(subscription);
        case "entitlements.active_entitlement_summary.updated":
          subscription = (Subscription) stripeObject;
          // Then define and call a function to handle the event
          // entitlements.active_entitlement_summary.updated
          // handleEntitlementUpdated(subscription);
          // ... handle other event types
        default:
          System.out.println("Unhandled event type: " + event.getType());
      }
      response.status(200);
      return "";
    });
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)
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)
## Próximas etapas

#### [Atualizar preços de assinatura](https://docs.stripe.com/billing/subscriptions/change-price.md)

Atualize as assinaturas para gerenciar os clientes que fazem upgrade ou downgrade de planos de preços.

#### [Aplicar pro rata](https://docs.stripe.com/billing/subscriptions/prorations.md)

Saiba como ajustar a fatura de um cliente para refletir com precisão alterações de preços no meio do ciclo.

#### [Oferecer upsells](https://docs.stripe.com/payments/checkout/upsells.md)

Incentive os clientes com descontos para intervalos mais longos de faturamento.
