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:

Captura de tela do painel Stripe

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 ou mensal . Configuraremos pagamentos recorrentes se a assinatura for definida como mensal

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 e paymentMethod 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ção parseInt ()

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 API fetch
  • 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:

Captura de tela do aplicativo React em branco

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 ( 
setEmail (e.target.value)} placeholder="Endereço de e-mail" /> setAmount (e.target.value)} placeholder="Quantidade" />
setSubscription ("onetime")} verificado={assinatura==="única"} /> Um tempo
setSubscription ("mensal")} verificado={assinatura==="mensal"} /> Por mês
); } 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 ( 
setEmail(e.target.value)} placeholder="E-mail Address" /> setAmount(e.target.value)} placeholder="Amount" />
setSubscription("onetime")} checked={subscription==="onetime"} /> Onetime
setSubscription("monthly")} checked={subscription==="monthly"} /> Por mês
); } 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.