Vivemos em um mundo onde interagimos com muitos serviços online e fazemos pagamentos para esses serviços por meio de gateways de pagamento online. E nós, como desenvolvedores, temos a responsabilidade de integrar esses gateways de pagamento de forma que seja seguro para o usuário e para a parte que está recebendo o pagamento.
Neste artigo, abordaremos como implementar a proteção 3D Secure ao aceitar pagamentos online usando Stripe.
O que é 3D Secure?
3D Secure é uma forma do Stripe autenticar um usuário antes de processar o pagamento. Quando um usuário insere os detalhes do cartão, ele é solicitado com um pop-up ou um redirecionamento para autenticar o pagamento.
Geralmente, é verificar a identidade via OTP, mas pode depender do banco emissor do cartão. Em alguns países, o 3D Secure não é necessário, mas em países como a Índia, o 3D Secure é necessário.
Você pode definir suas regras de radar em sua conta do Stripe para exigir autenticação 3D Secure, mas não adianta se você não tiver o código em seu formulário de pagamento para fazer um pop-up 3D Secure funcionar.
Neste artigo, criaremos um aplicativo da web simples de doação feito usando NodeJS, React e, claro, Stripe. Abordaremos os seguintes tópicos:
- Configurando o Stripe e obtendo as chaves de API
- Configurando um back end NodeJS e um front end React
- Criação de um formulário de checkout no front end
- Processando pagamentos da maneira usual
- Usar 3D Secure como substituto se a autenticação for necessária
- Confirmação do pagamento
- Adicionando pagamentos recorrentes (assinaturas)
- Testando nossa integração
O que você precisa?
- Um editor de código-prefiro VSCode , mas você pode usar qualquer editor de código do seu escolha
- NodeJS instalado
- Uma conta Stripe
- Conhecimento básico de linha de comando
- Conhecimento básico de ReactJS e NodeJS
Vamos começar!
Primeiro, vamos trabalhar no back-end. Eu prefiro uma “abordagem de API primeiro”, o que significa que você primeiro cria uma API e depois trabalha no resto do front end.
Criaremos nosso back end usando NodeJS, Express e um pacote Stripe para buscar o conteúdo relacionado ao pagamento.
Iniciando o back end
Vamos criar nosso back end. Para fazer isso, abra o terminal/prompt de comando e digite o seguinte comando para iniciar um projeto NodeJS na pasta desejada:
npm init-y
Executar este comando irá gerar um arquivo package.json
na pasta.
Agora abra o VSCode na pasta usando o seguinte comando para que possamos começar a editar:
código
.
Agora que o VSCode está aberto, você pode usar o terminal integrado, o que tornará sua vida mais fácil. Basta pressionar Ctrl + J no Windows ou Command + J no Mac para abrir o terminal no VSCode.
Vamos instalar alguns pacotes que nos ajudarão ainda mais com o projeto. Digite o seguinte comando no terminal e veremos o que esses pacotes fazem:
npm install express cors stripe dotenv
Estes são os pacotes sendo instalados:
-
Express
é usado para criar servidores HTTP facilmente -
CORS
nos ajuda a nos livrar de erros de origem cruzada em nossos aplicativos cliente -
Stripe
é a conexão real com o Stripe. Podemos obter detalhes de pagamento e criar pagamentos usando este pacote -
Dotenv
nos ajuda a habilitar variáveis de ambiente para armazenar dados confidenciais
Adicionando uma chave secreta do Stripe às variáveis de ambiente
Antes de prosseguir com este sistema de pagamento, vamos configurar a chave secreta do Stripe na variável de ambiente.
Todas as chaves e credenciais secretas da API devem ser armazenadas em variáveis de ambiente para que os dados não sejam roubados se o código real for roubado.
Para obter sua chave secreta do Stripe, abra seu painel do Stripe e você verá um menu lateral semelhante à imagem abaixo:
Agora, clique em Desenvolvedores e depois em Chaves de API . Lá você deverá ver sua chave publicável e secreta do Stripe.
Por enquanto, precisamos da chave secreta. Observe que você não deve compartilhar sua chave secreta com ninguém. Compartilhar sua chave secreta dará a outras pessoas acesso à sua conta do Stripe.
Por outro lado, a chave publicável é aquela que usamos no front end e não importa se alguém tem acesso a ela, porque é para ser pública.
Agora, copie sua chave secreta do Stripe e vá para VSCode, crie um novo arquivo chamado .env
e cole a chave no seguinte formato:
STRIPE_SECRET_KEY=(chave secreta aqui)
O arquivo .env
é usado para armazenar variáveis de ambiente. O pacote dotenv
irá procurar por este arquivo para carregar as variáveis de ambiente. Agora que o arquivo .env
está pronto, não precisamos mexer nas variáveis de ambiente novamente neste tutorial.
Instalando o Nodemon
Enquanto segue o tutorial, pode ser necessário reiniciar o servidor várias vezes. Para evitar isso, podemos instalar um pacote global chamado nodemon
que irá reiniciar automaticamente nosso servidor sempre que salvarmos um arquivo. Você pode ler mais sobre Nodemon aqui .
Digite o seguinte comando no terminal:
npm install-g nodemon
Use sudo
se necessário porque o Nodemon deve ser instalado globalmente, portanto, ele exigirá permissões de root.
Configurando um servidor Express
Vamos criar o arquivo que irá rodar nosso servidor. Podemos chamá-lo de index.js
porque é especificado como main
por padrão no arquivo package.json
. Você pode alterar o nome se quiser, mas vamos ficar com index.js
neste tutorial.
Vamos começar criando um servidor Express e uma rota simples:
const express=require ("express"); const app=express (); const PORT=process.env.PORT || 5000; const cors=require ("cors"); app.use (cors ()); app.use (express.json ()); app.use (express.urlencoded ({extended: true})); app.get ("/", (req, res)=> res.json ({status: 200, mensagem:"API Works"})); app.listen (PORT, ()=> console.log (`Servidor rodando na porta $ {PORT}`));
Isso cria um servidor Express simples com uma rota inicial, que simplesmente retorna um JSON dizendo que a API funciona.
Aqui, definimos a porta para process.env.PORT || 5000
porque se você decidir implantar este servidor em um serviço como o Heroku, eles irão hospedá-lo em suas próprias portas que são armazenadas em suas variáveis de ambiente, então deixamos eles decidirem a porta. Se process.env.PORT
for indefinido, o aplicativo está sendo executado localmente e a porta 5000 será usada.
Usamos o pacote cors
como um middleware Express para que os aplicativos clientes possam interagir com nosso servidor de maneira adequada, sem erros de origem cruzada. Você pode configurar o pacote cors
de acordo com suas necessidades, mas para este tutorial, permitiremos apenas qualquer tráfego.
Na seção de middleware, também permitimos JSON e dados codificados por URL por meio de um corpo de solicitação e o Express irá analisá-los para nós automaticamente.
Agora, se você for ao Postman ou qualquer outro cliente HTTP e executar uma solicitação GET em http://localhost: 5000
, você obterá a seguinte resposta JSON:
{ "status": 200, "message":"API funciona" }
Se você vir esta mensagem, seu servidor Express está configurado corretamente. Agora vamos para a próxima etapa.
Configurando dotenv
Agora, vamos configurar o pacote dotenv
para que ele possa reconhecer corretamente nossas variáveis de ambiente do arquivo .env
. Escreva o seguinte código no topo:
require ("dotenv"). config ();
Inicializando Stripe
Agora vamos configurar nossa conexão com o Stripe. Anteriormente no tutorial, instalamos um pacote chamado stripe
que nos ajudará a nos comunicar com o Stripe. Mas, primeiro, precisamos fornecer nossa chave secreta do Stripe para que ele possa interagir com nossa conta do Stripe.
Inclua este snippet na parte superior do arquivo que criamos anteriormente:
const Stripe=require ("stripe"); const stripe=Stripe (process.env.STRIPE_SECRET_KEY);
Anteriormente, lidamos com variáveis de ambiente e é aqui que usamos a STRIPE_SECRET_KEY
que armazenamos. Agora Stripe reconhece sua conta e podemos interagir ainda mais com Stripe.
Todo o código até agora deve exibir o seguinte:
require ("dotenv"). config (); const express=require ("express"); const app=express (); const PORT=process.env.PORT || 5000; const cors=require ("cors"); const Stripe=require ("stripe"); const stripe=Stripe (process.env.STRIPE_SECRET_KEY); app.use (cors ()); app.use (express.json ()); app.use (express.urlencoded ({extended: true})); app.get ("/", (req, res)=> res.json ({status: 200, mensagem:"API Works"})); app.listen (PORT, ()=> console.log (`Servidor rodando na porta $ {PORT}`));
Coleta de dados para pagamento
Vamos pensar em quais dados precisamos coletar do usuário para iniciar o pagamento. Manteremos as coisas simples por causa deste tutorial:
- endereço de e-mail
- Valor do pagamento
-
paymentMethod
, um ID gerado pelo Stripe no front end que representará um cartão específico - Assinatura,
única
oumensal
. Configuraremos pagamentos recorrentes se a assinatura for definida comomensal
Como estamos “criando” um pagamento, usaremos uma solicitação POST. Outro motivo para usar a solicitação POST é que os dados que enviamos ao servidor não são exibidos na própria URL, ao contrário de uma solicitação GET. Além disso, as solicitações GET podem ser acessadas diretamente pelo navegador e isso não é algo que desejamos.
Então, vamos criar um listener de solicitação POST e coletar dados:
app.post ("/donate", assíncrono (req, res)=> { tentar { deixe {e-mail, valor, método de pagamento, assinatura}=req.body; if (! email ||! amount ||! paymentMethod ||! assinatura) return res.status (400).json ({status: 400, mensagem:"Todos os campos são obrigatórios!"}); montante=parseInt (montante); if (assinatura==="única") { //Código de pagamento único aqui } if (assinatura==="mensal") { //Código de pagamento recorrente aqui } res.status (400).json ({status: 400, mensagem:"Tipo inválido"}); } catch (errar) { console.error (err); res.status (500).json ({status: 200, mensagem:"Erro interno do servidor"}); } });
No código acima, estamos fazendo o seguinte:
- Configurando um ouvinte POST na rota
/donate
, é claro - Coleta de
email
,amount
epaymentMethod
do usuário - Validando os campos, de forma que se algum dos campos estiver faltando, uma mensagem de erro será enviada
- Às vezes, o aplicativo cliente pode enviar
amount
como uma string, caso em que estamos convertendo a quantia em um valor inteiro usando a funçãoparseInt ()
Primeiro, lidaremos com pagamentos únicos.
Tentativa de pagamento HTTP simples
Usamos 3D Secure apenas se necessário ou de acordo com nossas regras de radar no painel do Stripe. Devemos tentar um pagamento HTTP antes de passar para o 3D Secure porque alguns cartões não são compatíveis com o 3D Secure.
Agora é hora de entrar em contato com Stripe:
const paymentIntent=esperar stripe.paymentIntents.create ({ montante: Math.round (montante * 100), moeda:"INR", recibo_email: email, descrição:"Pagamento por doação", método_de_pagamento: método_de_pagamento, confirme: verdadeiro });
Isso inicia o pagamento imediatamente. O campo confirm
diz ao Stripe para confirmar o pagamento assim que o receber. Se você não especificar confirm
, não cobrará do usuário e você precisará confirmar o pedido manualmente antes de fazer outra solicitação ao Stripe.
No campo montante
, você especifica a unidade monetária secundária (por exemplo, USD é centavos e INR é paisa). Math.round ()
é usado aqui para remover decimais, porque Stripe não gosta de números decimais.
Especifique a moeda de acordo com a localização da sua conta Stripe. Para mim é Índia, então uso INR
na moeda.
Assim que o pagamento for concluído, o recibo será enviado para o e-mail especificado. Nesse caso, mencionamos o e-mail que coletamos do usuário.
Agora vamos verificar se esse pagamento simples de HTTP foi bem-sucedido. Para fazer isso, podemos verificar a propriedade de status de paymentIntent
:
if (paymentIntent.status==="sucesso") { //Pagamento bem sucedido! return res.json ({ status: 200, mensagem:"Pagamento bem sucedido!", id: paymentIntent.id }); } >
Isso tudo por um simples pagamento HTTP. Aqui, paymentIntent.id
pode ser usado como um ID de pagamento. E usamos return
para interromper a execução imediata para que não haja erros inesperados.
No entanto, se o status não for bem-sucedido
, mas requires_action
, significa que 3D Secure é necessário. Então, aqui está como lidaremos com 3D Secure:
- Obteremos um
client_secret
para a intenção de pagamento - Enviaremos o
client_secret
para o front end - O front end usará o
client_secret
para autenticar usando 3D seguro - Faremos uma rota no back-end para verificar o status do pagamento novamente
Obtendo client_secret
e enviando-o para o front end
Vamos verificar se a intenção de pagamento que criamos requer 3D Secure e, em seguida, enviaremos o segredo do cliente:
if (paymentIntent.status==="requires_action") { return res.json ({ status: 200, mensagem:"3D seguro necessário", actionRequired: true, clientSecret: paymentIntent.client_secret }); }
Assim, enviamos o segredo do cliente para o front end. Lidaremos com o front end posteriormente neste artigo, assim que terminarmos com a parte do back end.
E por último, se o status não for sucesso
nem require_action
, informaremos ao usuário que o pagamento falhou. Usamos return
em casos anteriores, então não precisamos usar else
:
return res.status (400).json ({ status: 400, mensagem:"O pagamento falhou!" });
Tratamento de pagamentos recorrentes
Não usamos intenções de pagamento diretamente em pagamentos recorrentes. O processo para criar um pagamento recorrente é um pouco diferente:
- Primeiro, criamos um preço, que será o valor da nossa doação
- Em seguida, criamos um cliente Stripe com o e-mail do usuário
- Em seguida, criamos uma assinatura e cobramos do cliente o preço. Stripe enviará um e-mail ao cliente a cada mês para o pagamento se a autenticação for necessária
- Por fim, fazemos com que o usuário pague a primeira fatura em nosso próprio site
Anteriormente, criamos uma instrução if
para o tipo de assinatura mensal
. Todo o código de pagamento recorrente vai lá.
Criando um preço
Vamos passar para a primeira etapa, criando um preço:
preço const=espera stripe.prices.create ({ quantidade_da_unidade: Math.round (quantidade * 100), recorrente: {intervalo:"mês"}, moeda:"INR", informações do produto: { nome:"Doação recorrente" } });
Aqui, o unit_amount
é a quantidade real-já discutimos como isso é enviado ao Stripe.
Também fornecemos recorrente
com um intervalo
. Neste caso, definimos como mês
. O objeto product_data
contém algumas informações sobre o próprio produto. Nesse caso, é apenas uma doação, então apenas especificamos.
Criação de um cliente
Agora, vamos criar o cliente:
const cliente=espera stripe.customers.create ({ o email, descrição:"Cliente de doação", método_de_pagamento: método_de_pagamento, invoice_settings: { default_payment_method: paymentMethod } });
Aqui especificamos o paymentMethod
para que possamos cobrar do cliente imediatamente quando necessário, sem complicações.
Criação de uma assinatura
É aqui que o cliente é realmente cobrado. Ao iniciar uma assinatura, é gerada uma fatura que pode ser paga pelo usuário, mas faremos com que o usuário pague a fatura imediatamente para iniciar a assinatura.
Podemos obter o paymentIntent
da assinatura e, em seguida, podemos fazer as verificações como fazíamos antes:
const subscribe=await stripe.subscriptions.create ({ cliente: cliente.id, itens: [{price: price.id}], expandir: ["latest_invoice.payment_intent"] });
Estamos passando a ID de cliente e preço, vinculando tudo junto. Além disso, para obter acesso ao paymentIntent
da última fatura, usamos a propriedade expand
.
Enquanto tentamos criar uma assinatura, Stripe já tenta um pagamento baseado em HTTP. Agora precisamos cuidar dos pagamentos 3D seguros da mesma forma que fazíamos antes:
if ( subscribe.latest_invoice.payment_intent.status==="requer_ação" ) { //prossiga para o 3ds return res.status (200).json ({ status: 200, mensagem:"3D Secure necessário", actionRequired: true, clientSecret: subscribe.latest_invoice.payment_intent.client_secret, id: subscribe.latest_invoice.payment_intent.id, }); } if (subscribe.latest_invoice.payment_intent.status==="sucesso") { return res.json ({ status: 200, mensagem:"Pagamento com sucesso!", }); } retornar res.status (400).json ({status: 400, mensagem:"Falha no pagamento!"});
É o mesmo método que usamos para os pagamentos únicos. Terminamos com a rota de pagamento no back-end.
Há mais uma rota a percorrer-a rota de verificação. Após a autenticação no front end, precisamos de uma rota para verificar e verificar o status com o back end:
app.get ("/check/: id", assíncrono (req, res)=> { tentar { const id=req.params.id; const paymentIntent=esperar stripe.paymentIntents.retrieve (id); if (paymentIntent?.status==="sucesso") { return res.json ({ status: 200, mensagem:"Pagamento com sucesso!", eu ia, }); } res .status (400) .json ({ status: 200, mensagem:"O pagamento falhou! Tente novamente mais tarde.", }); } catch (errar) { console.error (err); res.status (500).json ({status: 500, mensagem:"Erro interno do servidor"}); } });
Desta vez, usamos uma solicitação GET e verificamos se o pagamento foi realmente concluído. Isso pode ser feito se você não quiser usar um webhook e quiser fornecer um serviço virtual ao usuário imediatamente.
Este é o lugar para seu aplicativo saber se um pagamento foi realizado com sucesso e que o usuário está pronto para prosseguir. Mas, neste caso, este é um site de doação e não precisamos fazer nada de especial aqui.
Complete o código index.js
Seu arquivo index.js
agora deve ter a seguinte aparência:
require ("dotenv"). config (); const express=require ("express"); const app=express (); const PORT=process.env.PORT || 5000; const cors=require ("cors"); const Stripe=require ("stripe"); const stripe=Stripe (process.env.STRIPE_SECRET_KEY); app.use (cors ()); app.use (express.json ()); app.use (express.urlencoded ({extended: true})); app.get ("/", (req, res)=> res.json ({status: 200, mensagem:"API Works"})); app.post ("/doar", assíncrono (req, res)=> { tentar { deixe {email, valor, método de pagamento, assinatura}=req.body; if (! email ||! amount ||! paymentMethod ||! assinatura) return res.status (400).json ({status: 400, mensagem:"Todos os campos são obrigatórios!"}); montante=parseInt (montante); if (assinatura==="única") { //Código de pagamento único aqui const paymentIntent=await stripe.paymentIntents.create ({ montante: Math.round (montante * 100), moeda:"INR", recibo_email: email, descrição:"Pagamento por doação", método_de_pagamento: método_de_pagamento, confirme: verdadeiro }); if (paymentIntent.status==="bem-sucedido") { //Pagamento bem sucedido! return res.json ({ status: 200, mensagem:"Pagamento bem sucedido!", id: paymentIntent.id }); } if (paymentIntent.status==="require_action") { return res.json ({ status: 200, mensagem:"3D seguro necessário", actionRequired: true, clientSecret: paymentIntent.client_secret }); } return res.status (400).json ({ status: 400, mensagem:"O pagamento falhou!" }); } if (assinatura==="mensal") { //Código de pagamento recorrente aqui preço const=espera stripe.prices.create ({ quantidade_da_unidade: Math.round (quantidade * 100), recorrente: {intervalo:"mês"}, moeda:"INR", informações do produto: { nome:"Doação recorrente" } }); const customer=await stripe.customers.create ({ o email, descrição:"Cliente de doação", método_de_pagamento: método_de_pagamento, invoice_settings: { default_payment_method: paymentMethod } }); const subscribe=await stripe.subscriptions.create ({ cliente: cliente.id, itens: [{price: price.id}], expandir: ["latest_invoice.payment_intent"] }); E se ( subscribe.latest_invoice.payment_intent.status==="requer_ação" ) { //prossiga para o 3ds return res.status (200).json ({ status: 200, mensagem:"3D Secure necessário", actionRequired: true, clientSecret: subscribe.latest_invoice.payment_intent.client_secret, id: subscribe.latest_invoice.payment_intent.id, }); } if (subscribe.latest_invoice.payment_intent.status==="sucesso") { return res.json ({ status: 200, mensagem:"Pagamento com sucesso!", }); } retornar res.status (400).json ({status: 400, mensagem:"O pagamento falhou!"}); } res.status (400).json ({status: 400, mensagem:"Tipo inválido"}); } catch (errar) { console.error (err); res.status (500).json ({status: 200, mensagem:"Erro interno do servidor"}); } }); app.listen (PORT, ()=> console.log (`Servidor rodando na porta $ {PORT}`));
Criação do front end
Agora vamos passar para o front-end para aprender como acionar a autenticação 3D Secure e como iniciar pagamentos.
Não faremos nenhum estilo sofisticado no front-end. Vamos mantê-lo simples e nos concentrar no lado do pagamento.
Usaremos React no front end. Crie uma nova pasta chamada frontend
, abra o terminal nessa pasta e digite o seguinte comando:
npx criar-reagir-app.
O .
especifica que estamos criando um aplicativo React na própria pasta atual.
Agora vamos instalar alguns pacotes de que precisaremos ao fazer este aplicativo:
npm install axios @ stripe/react-stripe-js @ stripe/stripe-js
-
axios
é uma biblioteca para fazer solicitações HTTP facilmente sem mexer com a APIfetch
- Ambos os pacotes Stripe são úteis para criar Stripe Elements e se comunicar com o Stripe
Agora abra o VSCode no aplicativo React usando o seguinte comando:
código
.
Uma vez no terminal integrado, digite o seguinte comando para iniciar o aplicativo React:
npm start
Uma nova guia do navegador deve abrir e você verá a seguinte tela:
Se vir esta tela, você iniciou com sucesso um aplicativo React. Agora vamos fazer uma limpeza.
Exclua os seguintes arquivos em src
, dos quais não precisamos:
App.test.js
setupTests.js
logo.svg
Depois de excluir esses arquivos, você verá uma janela pop-up de erro. Isso porque quebramos algumas coisas.
Vá para App.js
e remova a importação do logotipo na parte superior e o conteúdo sob o primeiro div
. Remova tudo em App.css
.
Seu App.js
deve ser parecido com isto:
import"./App.css"; function App () { return; } exportar aplicativo padrão;
A seguir, vamos criar um novo componente chamado Checkout
. Crie dois arquivos em src
: Checkout.js
e Checkout.css
.
Como não estamos nos concentrando em estilo neste tutorial, estou fornecendo o conteúdo de um arquivo CSS, mas não vamos passar pelo que realmente está acontecendo aqui em Checkout.css
:
.checkout { display: flex; alinhar-itens: centro; justificar o conteúdo: centro; altura: 100vh; largura: 100%; } .checkout__container { cor de fundo: # f5f5f5; preenchimento: 20px; largura: 25%; display: flex; direção flexível: coluna; } .checkout__textBox { preenchimento: 10px; tamanho da fonte: 18px; margin-bottom: 10px; } .checkout__radio { margin-bottom: 10px; } .checkout__btn { margem superior: 10px; preenchimento: 10px; tamanho da fonte: 18px; fronteira: nenhum; cor de fundo: # 0984e3; cor branca; }
Agora, abra Checkout.js
e crie um componente funcional React:
import React from"react"; function Checkout () { return; } exportar Checkout padrão;
Agora vamos importar este componente e usá-lo no App.js
:
importar {Elements} de"@ stripe/react-stripe-js"; importar {loadStripe} de"@ stripe/stripe-js"; import"./App.css"; importar Checkout de"./Checkout"; const stripePromise=loadStripe ("(chave publicável aqui)"); function App () { Retorna (); } exportar aplicativo padrão;
Envolvemos nosso componente Checkout
dentro dos Elementos
fornecidos pelo Stripe. Este componente atua como um wrapper para todos os elementos e serviços do Stripe de que precisamos.
Usamos a função loadStripe ()
e passamos a chave publicável, e então passamos stripePromise
como stripe
no Elementos
componente como adereços.
Agora vamos para Checkout.js
e façamos o layout básico do nosso formulário:
importar {CardElement} de"@ stripe/react-stripe-js"; import React, {useState} de"react"; function Checkout () { const [email, setEmail]=useState (""); const [quantidade, setAmount]=useState (""); const [assinatura, setSubscription]=useState ("onetime"); const handleSubmit=async (e)=> { tentar { e.preventDefault (); } catch (erro) { console.error (erro); alerta ("O pagamento falhou!"); } }; Retorna (); } exportar Checkout padrão;
Criamos um formulário básico solicitando o e-mail e a quantidade desejada. O componente CardElement
é usado para mostrar um pequeno elemento para o usuário inserir os detalhes do cartão.
Agora, vamos lidar com o evento quando o usuário enviar o formulário:
const handleSubmit=async (e)=> { tentar { e.preventDefault (); if (! elementos ||! stripe) return; const cardElement=elements.getElement (CardElement); const {erro, paymentMethod}=espera stripe.createPaymentMethod ({ tipo:"cartão", card: cardElement, }); } catch (erro) { console.error (erro); alerta ("O pagamento falhou!"); } };
Primeiro, verificaremos se Stripe e Elementos estão carregados. Caso contrário, o formulário não fará nada. Como você pode processar um pagamento sem carregar o Stripe?
Então chegamos ao cardElement
. A razão pela qual é muito fácil de encontrar é porque só pode haver um CardElement
em todo o formulário.
A seguir, criamos um paymentMethod
a partir dos detalhes inseridos em cardElement
, que por sua vez retornará um objeto contendo o ID da forma de pagamento, que exigimos no back end.
Agora vamos chegar ao fim e processar o pagamento.
Primeiramente, vamos importar axios
:
importar axios de"axios"
Então, vamos fazer uma solicitação ao nosso back end fornecendo informações sobre o pagamento:
const res=await axios.post ("http://localhost: 5000/donate", { resultar, o email, inscrição, stripeToken: paymentMethod.id, });
Se houver um erro na solicitação ou se o código de resposta apontar para um erro, a execução do código será interrompida e irá para o bloco catch
para lidar com o erro.
Agora, o back end tentará realizar um pagamento HTTP simples e obteremos uma resposta. If we need 3D secure, actionRequired
will be true
:
if (res.data.actionRequired) { //We perform 3D Secure authentication const { paymentIntent, error }=await stripe.confirmCardPayment( res.data.clientSecret ); if (error) return alert("Error in payment, please try again later"); if (paymentIntent.status==="succeeded") return alert(`Payment successful, payment ID-${res.data.id}`); const res2=await axios.get(`http://localhost:5000/check/${res.data.id}`); alert(`Payment successful, payment ID-${res.data.id}`); } else { //Simple HTTP Payment was successful alert(`Payment successful, payment ID-${res.data.id}`); }
Here, we check if actionRequired
is true
. If it is, we need to trigger a 3D Secure authentication popup. We do that by passing in the clientSecret
we get from server to confirmCardPayment()
function from stripe
.
Then, we get back the paymentIntent
and check the payment from our server by sending the payment intent ID to the /check
route of our Express server. The route returns a 200 status code if the payment was successful, otherwise our code will go through the catch
block as explained before.
So that’s how you trigger 3D Secure. Here’s the complete code of Checkout.js
:
import { CardElement } from"@stripe/react-stripe-js"; import React, { useState } from"react"; import axios from"axios"; function Checkout() { const [email, setEmail]=useState(""); const [amount, setAmount]=useState(""); const [subscription, setSubscription]=useState("onetime"); const handleSubmit=async (e)=> { try { e.preventDefault(); if (!elements || !stripe) return; const cardElement=elements.getElement(CardElement); const { error, paymentMethod }=await stripe.createPaymentMethod({ type:"card", card: cardElement, }); const res=await axios.post("http://localhost:5000/donate", { amount, email, subscription, stripeToken: paymentMethod.id, }); if (res.data.actionRequired) { //We perform 3D Secure authentication const { paymentIntent, error }=await stripe.confirmCardPayment( res.data.clientSecret ); if (error) return alert("Error in payment, please try again later"); if (paymentIntent.status==="succeeded") return alert(`Payment successful, payment ID-${res.data.id}`); const res2=await axios.get(`http://localhost:5000/check/${res.data.id}`); alert(`Payment successful, payment ID-${res.data.id}`); } else { //Simple HTTP Payment was successful alert(`Payment successful, payment ID-${res.data.id}`); } } catch (error) { console.error(error); alert("Payment failed!"); } }; return (); } export default Checkout;
To test your Stripe integration, here are some card details provided by Stripe to test. You need to be on test mode to use these cards, and you will not be charged.
A popup will be opened when you enter the card with 3D Secure. In production environments, the user will be sent an SMS to their phone number to authenticate the payment.
You can set your Radar rules to force 3D Secure for supported cards, just be aware that Radar rules are not available for all countries.
What’s Next?
I recommend checking out more from Stripe, like Apple Pay, Google Pay, saved cards, off-session payment, and the multiple other payment methods offered.
You can also check out Stripe Checkout, where you just need to pass in products and the payment will be handled by Stripe.
The post Implementing 3D Secure in Stripe appeared first on LogRocket Blog.