# Pagamentos em cartão com autenticação bancária
Crie uma integração mais simples com limitações regionais.
Esta integração funciona para empresas que só aceitam cartões dos EUA e do Canadá. Ela é inicialmente mais simples, mas não permite atender clientes globais no futuro.
### Como funciona essa integração
Os bancos em regiões como a Europa e a Índia geralmente exigem autenticação de dois fatores para confirmar uma compra. Se você opera principalmente nos Estados Unidos e no Canadá, ignorar a *autenticação do cartão* (A bank might require the customer to authenticate a card payment before processing. Implementation varies by bank but commonly consists of a customer entering in a security code sent to their phone) pode simplificar sua integração, pois os bancos raramente a solicitam nessas regiões.
Quando o banco exige autenticação, esta integração básica imediatamente recusa o pagamento (como uma recusa de cartão), em vez de gerenciar a autenticação para finalizar o pagamento de forma assíncrona. A vantagem é que o pagamento é aprovado ou recusado imediatamente, e a confirmação acontece no servidor, de forma que você pode seguir para as ações pós-pagamento imediatamente sem um *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests).
### Como se compara à integração global
| Recurso | Esta integração | Integração global |
| -------------------------------------------------------------------------------- | --------------- | ----------------- |
| Formulário de pagamento personalizado | ✔ | ✔ |
| Dados sensíveis nunca chegam ao seu servidor | ✔ | ✔ |
| Funciona para seus clientes nos EUA e Canadá | ✔ | ✔ |
| Recusa pagamentos com dados do cartão incorretos ou sem fundos | ✔ | ✔ |
| Recusa pagamentos com solicitações de autenticação bancária | ✔ | |
| Funciona para seus clientes globais | | ✔ |
| Gerencia automaticamente pagamentos no cartão que exigem autenticação bancária | | ✔ |
| Webhooks são recomendados para tarefas pós-pagamento | | ✔ |
| Fácil de expandir para outras formas de pagamento (por exemplo, débito bancário) | | ✔ |
Empresas em crescimento ou que já são multinacionais devem usar a [integração global](https://docs.stripe.com/payments/accept-a-payment.md) da Stripe para aceitar solicitações de autenticação de dois fatores e permitir que o cliente use mais formas de pagamento.
Fluxo de pagamentos durante a integração (See full diagram at https://docs.stripe.com/payments/without-card-authentication)
## Criar um formulário de checkout [Lado do cliente]
O [Elements](https://docs.stripe.com/payments/elements.md), parte do Stripe.js, oferece componentes inseríveis na IU com o objetivo de coletar dados de cartão dos clientes. A Stripe os hospeda e os coloca em seu formulário de pagamento em iframes, para que os dados do cartão do cliente nunca se misturem com seu código.
#### HTML + JS
Primeiro, inclua o [Stripe.js](https://docs.stripe.com/js.md) no cabeçalho de todas as páginas do seu site.
```html
```
Incluir o script em todas as páginas do site permite aproveitar as [funções avançadas de fraude](https://docs.stripe.com/radar.md) da Stripe e a detecção de comportamentos anormais de navegação.
### Requisitos de segurança
Este script sempre deve ser carregado diretamente de **js.stripe.com** para manter a [conformidade com PCI](https://docs.stripe.com/security/guide.md). Não é possível inserir o script em pacotes ou hospedar sua própria cópia.
Ao usar o Elements, todos os dados de pagamento são enviados por uma conexão HTTPS segura.
O endereço da página que contém o Elements também precisa começar com **https://**, e não **http://**. Saiba como obter certificados SSL e integrá-los ao seu servidor para habilitar uma conexão HTTPS segura na documentação sobre [segurança](https://docs.stripe.com/security.md).
### Adicione o Elements à sua página
Em seguida, você precisa de uma conta Stripe. [Cadastre-se aqui](https://dashboard.stripe.com/register).
Crie elementos DOM vazios (contêineres) com IDs exclusivos no seu formulário de pagamento.
```html
```
Crie uma instância do [objeto Stripe](https://docs.stripe.com/js.md#stripe-function), fornecendo sua [chave de API](https://docs.stripe.com/keys.md) publicável como o primeiro parâmetro. Em seguida, crie uma instância do [objeto Elements](https://docs.stripe.com/js.md#stripe-elements) e use-a para [montar](https://docs.stripe.com/js.md#element-mount) um elemento Card no contêiner de elementos DOM vazio da página.
```javascript
const stripe = Stripe('<>');
const elements = stripe.elements();
const cardElement = elements.create('card');
cardElement.mount('#card-element');
```
Use [stripe.createPaymentMethod](https://docs.stripe.com/js/payment_methods/create_payment_method) no seu cliente para coletar os dados do cartão e criar um [PaymentMethod](https://docs.stripe.com/api/payment_methods.md) quando o cliente enviar o formulário de pagamento. Envie o ID do PaymentMethod para seu servidor.
```javascript
const form = document.getElementById("payment-form");
var resultContainer = document.getElementById('payment-result');
// cardElement is defined in the previous step
cardElement.on('change', function(event) {
if (event.error) {
resultContainer.textContent = event.error.message;
} else {
resultContainer.textContent = '';
}
});
form.addEventListener('submit', async event => {
event.preventDefault();
resultContainer.textContent = '';
const result = await stripe.createPaymentMethod({
type: 'card',
card: cardElement,
});
handlePaymentMethodResult(result);
});
const handlePaymentMethodResult = async ({ paymentMethod, error }) => {
if (error) {
// An error happened when collecting card details, show error in payment form
resultContainer.textContent = error.message;
} else {
// Send paymentMethod.id to your server (see Step 3)
const response = await fetch("/pay", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ payment_method_id: paymentMethod.id })
});
const responseJson = await response.json();
handleServerResponse(responseJson);
}
};
const handleServerResponse = async responseJson => {
if (responseJson.error) {
// An error happened when charging the card, show it in the payment form
resultContainer.textContent = responseJson.error;
} else {
// Show a success message
resultContainer.textContent = 'Success!';
}
};
```
#### React
Primeiro, instale o [Stripe.js](https://github.com/stripe/stripe-js) e o [Stripe.js do React](https://docs.stripe.com/sdks/stripejs-react.md).
```bash
npm install --save @stripe/stripe-js @stripe/react-stripe-js
```
> Este guia pressupõe que você já tenha um conhecimento básico do React e que já tenha configurado um projeto do React. Se você é novo no React, recomendamos que leia o guia do React [Começar](https://reactjs.org/docs/getting-started.html) antes de continuar.
>
> Se você está procurando uma maneira rápida de experimentar o React Stripe.js sem precisar criar um novo projeto, comece com esta [demonstração no CodeSandbox](https://codesandbox.io/s/react-stripe-official-q1loc?fontsize=14&hidenavigation=1&theme=dark).
### Requisitos de segurança
Ao usar o Elements, todos os dados de pagamento são enviados por uma conexão HTTPS segura.
O endereço da página que contém o Elements também precisa começar com **https://**, e não **http://**. Saiba como obter certificados SSL e integrá-los ao seu servidor para habilitar uma conexão HTTPS segura na documentação sobre [segurança](https://docs.stripe.com/security.md).
### Adicione Stripe.js e Elements à sua página
Para usar o Elements, insira a raiz de seu aplicativo React em um provedor do [Elements](https://docs.stripe.com/sdks/stripejs-react.md#elements-provider). Chame [loadStripe](https://github.com/stripe/stripe-js#loadstripe) com sua chave publicável e passe o parâmetro `Promise` retornado para o provedor do `Elements`.
Importe e chame o `loadStripe` na raiz do aplicativo React para aproveitar as [funções avançadas de fraude](https://docs.stripe.com/radar.md) da Stripe e a capacidade de detectar comportamentos anormais de navegação.
```jsx
import React from 'react';
import ReactDOM from 'react-dom';
import {Elements} from '@stripe/react-stripe-js';
import {loadStripe} from '@stripe/stripe-js';
import CheckoutForm from './CheckoutForm';
// Make sure to call `loadStripe` outside of a component’s render to avoid
// recreating the `Stripe` object on every render.
const stripePromise = loadStripe("<>");
function App() {
return (
);
};
ReactDOM.render(, document.getElementById('root'));
```
### Criar um PaymentMethod
Use o `CardElement` e [stripe.createPaymentMethod](https://docs.stripe.com/js/payment_methods/create_payment_method) no cliente para coletar os dados do cartão e criar um [PaymentMethod](https://docs.stripe.com/api/payment_methods.md) quando o cliente enviar o formulário de pagamento. Envie o ID do PaymentMethod para seu servidor.
Para chamar `stripe.createPaymentMethod` do seu componente de formulário de pagamentos, use os hooks [useStripe](https://docs.stripe.com/sdks/stripejs-react.md#usestripe-hook) e [useElements](https://docs.stripe.com/sdks/stripejs-react.md#useelements-hook). Se preferir componentes de classe tradicionais em vez de hooks, use um [ElementsConsumer](https://docs.stripe.com/sdks/stripejs-react.md#elements-consumer).
#### Hooks
```jsx
import React from 'react';
import {useStripe, useElements, CardElement} from '@stripe/react-stripe-js';
export default function CheckoutForm() {
const stripe = useStripe();
const elements = useElements();
const handleSubmit = async (event) => {
// We don't want to let default form submission happen here,
// which would refresh the page.
event.preventDefault();
const result = await stripe.createPaymentMethod({
type: 'card',
card: elements.getElement(CardElement),
billing_details: {
// Include any additional collected billing details.
name: 'Jenny Rosen',
},
});
handlePaymentMethodResult(result);
};
const handlePaymentMethodResult = async (result) => {
if (result.error) {
// An error happened when collecting card details,
// show `result.error.message` in the payment form.
} else {
// Otherwise send paymentMethod.id to your server (see Step 3)
const response = await fetch('/pay', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
payment_method_id: result.paymentMethod.id,
}),
});
const serverResponse = await response.json();
handleServerResponse(serverResponse);
}
};
const handleServerResponse = (serverResponse) => {
if (serverResponse.error) {
// An error happened when charging the card,
// show the error in the payment form.
} else {
// Show a success message
}
};
const handleCardChange = (event) => {
if (event.error) {
// Show `event.error.message` in the payment form.
}
};
return (
);
}
```
## Configurar a Stripe [Lado do servidor]
Use uma biblioteca oficial para fazer solicitações à API da Stripe pelo seu aplicativo:
#### Ruby
```bash
# Available as a gem
sudo gem install stripe
```
```ruby
# If you use bundler, you can add this line to your Gemfile
gem 'stripe'
```
## Fazer um pagamento [Lado do servidor]
Configure um endpoint no seu servidor para receber a solicitação do cliente.
A Stripe usa um objeto [PaymentIntent](https://docs.stripe.com/api/payment_intents.md) para representar sua intenção de coletar o pagamento de um cliente, acompanhando suas tentativas de cobrança e alterações no estado do pagamento durante todo o processo.
Sempre defina o valor a ser cobrado no servidor, que é um ambiente seguro, e não no cliente. Dessa forma, você evita que clientes mal-intencionados escolham os próprios preços.
Crie um endpoint HTTP para responder à solicitação do AJAX da etapa 1. Nesse endpoint, decida quanto cobrar do cliente. Para criar um pagamento, crie um PaymentIntent usando o ID de *PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) da etapa 1 com o código a seguir:
#### curl
```curl
# Check the status of the PaymentIntent to make sure it succeeded
curl https://api.stripe.com/v1/payment_intents \
-u <>: \
-d amount=1099 \
-d currency=usd \
# A PaymentIntent can be confirmed some time after creation,
# but here we want to confirm (collect payment) immediately.
-d confirm=true \
-d payment_method="{{PAYMENT_METHOD_ID}}" \
# If the payment requires any follow-up actions from the
# customer, like two-factor authentication, Stripe will error
# and you will need to prompt them for a new payment method.
-d error_on_requires_action=true
```
> Se você configurar [error_on_requires_action](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-error_on_requires_action) como `true` ao confirmar um pagamento, a Stripe recusa automaticamente o pagamento se ele solicitar autenticação de dois fatores do usuário.
#### Resposta da API Payment Intents
Quando você faz um pagamento com a API, a resposta inclui o status do PaymentIntent. Se o pagamento estiver correto, o status será `succeeded`.
```json
{
"id": "pi_0FdpcX589O8KAxCGR6tGNyWj",
"object": "payment_intent",
"amount": 1099,
"charges": {
"object": "list",
"data": [
{
"id": "ch_GA9w4aF29fYajT",
"object": "charge",
"amount": 1099,
"refunded": false,
"status": "succeeded",
}
]
},
"client_secret": "pi_0FdpcX589O8KAxCGR6tGNyWj_secret_e00tjcVrSv2tjjufYqPNZBKZc",
"currency": "usd",
"last_payment_error": null,"status": "succeeded",
}
```
Se o pagamento for recusado, a resposta conterá um código e uma mensagem erro. Veja este exemplo de um pagamento recusado porque o cartão exigia autenticação de dois fatores.
```json
{
"error": {"code": "authentication_required",
"decline_code": "authentication_not_handled",
"doc_url": "https://docs.stripe.com/error-codes#authentication-required",
"message": "This payment required an authentication action to complete, but `error_on_requires_action` was set. When you're ready, you can upgrade your integration to handle actions at https://stripe.com/docs/payments/payment-intents/upgrade-to-handle-actions.",
"payment_intent": {
"id": "pi_1G8JtxDpqHItWkFAnB32FhtI",
"object": "payment_intent",
"amount": 1099,
"status": "requires_payment_method",
"last_payment_error": {
"code": "authentication_required",
"decline_code": "authentication_not_handled",
"doc_url": "https://docs.stripe.com/error-codes#authentication-required",
"message": "This payment required an authentication action to complete, but `error_on_requires_action` was set. When you're ready, you can upgrade your integration to handle actions at https://stripe.com/docs/payments/payment-intents/upgrade-to-handle-actions.",
"type": "card_error"
},
},
"type": "card_error"
}
}
```
## Testar a integração
A Stripe fornece vários cartões de teste que você pode usar em uma *área restrita* (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) para assegurar que essa integração esteja pronta. Use-os com qualquer CVC, código postal e data de validade futura.
| Número | Descrição |
| ---------------- | --------------------------------------------------------------------------------------------------- |
| 4242424242424242 | Finaliza e processa o pagamento imediatamente. |
| 4000000000009995 | Sempre falha, com o código de recusa `insufficient_funds`. |
| 4000002500003155 | Exige autenticação, que nesta integração falha com o código de recusa `authentication_not_handled`. |
Veja a lista completa de [cartões de teste](https://docs.stripe.com/testing.md).
## Atualizar sua integração para aceitar autenticação de cartões
A integração dos seus pagamentos com cartões básicos está concluída. Esta integração **recusa cartões que exigem autenticação durante o pagamento**.
Se você começar a ver pagamentos no Dashboard listados como `Failed`, será necessário [atualizar sua integração](https://docs.stripe.com/payments/payment-intents/upgrade-to-handle-actions.md). A integração global da Stripe processa esses pagamentos em vez de recusá-los automaticamente.