
Este texto é uma adaptação de vários trechos do livro de Scott Hasbrouck, “The Node.js Engineer’s Guide to Stripe” – o senhor está lendo o livro e o que ele diz. Disponível agora! com um desconto de 10% para os leitores da David Walsh com o código: WALSH10
- Substituir Checkout.js por Stripe.js
- Remoção do botão Checkout.js
- Adicionar campos obrigatórios do Stripe
- Integração da ação do formulário com o Stripe.js
Quando o senhor cria uma integração com o Stripe pela primeira vez, a vantagem do Checkout.js em relação ao Stripe.js é a facilidade de integração e a velocidade de um aplicativo em funcionamento. No entanto, ele não permite adicionar nenhum campo de entrada adicional. Em muitas situações, o senhor desejará coletar outros valores, como Quantidade, um menu suspenso de produtos, endereço de entrega etc., e enviá-los com o mesmo formulário que coleta os detalhes de pagamento. Ou talvez o senhor queira apenas um estilo uniforme com o restante do aplicativo que não exija a exibição de uma caixa de diálogo modal. A biblioteca de front-end menor do Stripe, chamada Stripe.js, não inclui nenhum elemento de UI, mas tem toda a funcionalidade da API do lado do cliente para gerar tokens de pagamento. A personalização do formulário de pagamento não exigirá alterações na funcionalidade de back-end do seu aplicativo Node.js, porque o front-end ainda estará gerando o mesmo token de pagamento.
Breve visão geral da funcionalidade do Checkout.js
Se o senhor nunca integrou o Stripe antes, ou se já faz algum tempo que não o faz, vamos rever qual é a finalidade da parte front-end do Stripe! O Stripe é uma API como serviço, portanto, sua primeira pergunta pode ser: “Por que uma API exige o uso de uma biblioteca JavaScript de front-end?” Ótima pergunta! Como o senhor pode imaginar, lidar com as informações de cartão de crédito de seus usuários on-line é um negócio potencialmente arriscado, e é exatamente por isso que há um padrão de segurança ao qual o senhor deve aderir para aceitar pagamentos on-line. Os Padrões de Segurança Digital do Setor de Cartões de Pagamento (ou PCI DSS, comumente chamado apenas de PCI) proíbem explicitamente o armazenamento direto de números de cartão de crédito pelos comerciantes, a menos que o senhor esteja preparado para a tarefa de “proteger os dados armazenados do titular do cartão”. A engenhosidade do Stripe consistiu em criar um mecanismo simples de front-end que coleta os dados de pagamento do titular do cartão em seu nome, de modo que eles nunca chegam a entrar em contato com o seu servidor. Tornando a conformidade com o PCI-DSS muito mais fácil. Isso é abordado em mais detalhes em meu livro, The Node.js Engineer’s Guide to Stripe (Guia do engenheiro do Node.js para o Stripe).
O Checkout.js agrupa o mecanismo de coleta de dados do titular do cartão com um formulário pop-up modal bonito e fácil de integrar que coleta os detalhes de pagamento do usuário. Essa é uma opção fantástica para criar uma integração muito rápida com o Stripe, mas não fluirá perfeitamente com o restante da sua interface de usuário. É aqui que o Stripe.js entra em ação. A API ainda oferece métodos JavaScript para enviar os detalhes do pagamento diretamente ao Stripe e receber um token de pagamento para representar o pagamento.
O A documentação do Stripe lista fornece uma tag Script que carrega o Stripe.js com a versão mais recente. Pode ser tentador instalar o Script com o Bower, executando bower install --save stripe.js=https://js.stripe.com/v2/
, mas lembre-se de que fazer isso não é oficialmente endossado pelo Stripe. Não há menção sobre a frequência com que eles atualizam as bibliotecas do lado do cliente, portanto, algo pode quebrar inesperadamente. Portanto, sua primeira opção é simplesmente carregar a biblioteca colocando a tag de script fornecida pelo Stripe no arquivo HTML em que seu aplicativo React está montado:
<html> <head> <script type="text/javascript" src="https://js.stripe.com/v2/"></script> </head> <body style="margin: 0px;"> <div id="main"></div> <script src="react-bundle.js"></script> </body> <html>
A muito melhor opção seria carregar dinamicamente esse script com o ReactScriptLoader! Considerando que um aplicativo React é um aplicativo de página única, provavelmente há grandes partes do seu aplicativo que não têm um formulário de pagamento. Por que carregar o Stripe.js para toda a página quando podemos simplesmente carregá-lo apenas para o componente do formulário de pagamento? Vamos criar um componente React vazio para nosso formulário de pagamento e carregar dinamicamente o Stripe.js (observe que esse método também funcionaria para o Checkout.js!):
var React = require('react'); var ReactScriptLoaderMixin = require('react-script-loader').ReactScriptLoaderMixin; var PaymentForm = React.createClass({ mixins: [ ReactScriptLoaderMixin ], getInitialState: function() { return { stripeLoading: true, stripeLoadingError: false }; }, getScriptURL: function() { return 'https://js.stripe.com/v2/'; }, onScriptLoaded: function() { if (!PaymentForm.getStripeToken) { // Put your publishable key here Stripe.setPublishableKey('pk_test_xxxx'); this.setState({ stripeLoading: false, stripeLoadingError: false }); } }, onScriptError: function() { this.setState({ stripeLoading: false, stripeLoadingError: true }); }, render: function() { if (this.state.stripeLoading) { return <div>Loading</div>; } else if (this.state.stripeLoadingError) { return <div>Error</div>; } else { return <div>Loaded!</div>; } } }); module.exports = PaymentForm;
O ReactScriptLoaderMixin começa a carregar o script remoto e, após o carregamento bem-sucedido ou a ocorrência de um erro, invocará um dos dois ouvintes de eventos. Quando o script for carregado com êxito, poderemos definir a chave pública para o Stripe.js. Isso, por sua vez, nos dá uma condicional na função de renderização para três estados de carregamento, erro ou carregado! Observe que esse método também pode ser usado para carregar o Checkout.js.
Agora que temos um componente React com o Stripe.js carregado, vamos começar a criar o formulário de pagamento personalizado. No mínimo, precisamos coletar quatro valores para que o Stripe gere um token de pagamento para nós: número do cartão de crédito, mês de validade, ano de validade e cvc.
var React = require('react'); var ReactScriptLoaderMixin = require('react-script-loader').ReactScriptLoaderMixin; var PaymentForm = React.createClass({ mixins: [ ReactScriptLoaderMixin ], getInitialState: function() { return { stripeLoading: true, stripeLoadingError: false, submitDisabled: false, paymentError: null, paymentComplete: false, token: null }; }, getScriptURL: function() { return 'https://js.stripe.com/v2/'; }, onScriptLoaded: function() { if (!PaymentForm.getStripeToken) { // Put your publishable key here Stripe.setPublishableKey('pk_test_xxxx'); this.setState({ stripeLoading: false, stripeLoadingError: false }); } }, onScriptError: function() { this.setState({ stripeLoading: false, stripeLoadingError: true }); }, onSubmit: function(event) { var self = this; event.preventDefault(); this.setState({ submitDisabled: true, paymentError: null }); // send form here Stripe.createToken(event.target, function(status, response) { if (response.error) { self.setState({ paymentError: response.error.message, submitDisabled: false }); } else { self.setState({ paymentComplete: true, submitDisabled: false, token: response.id }); // make request to your server here! } }); }, render: function() { if (this.state.stripeLoading) { return <div>Loading</div>; } else if (this.state.stripeLoadingError) { return <div>Error</div>; } else if (this.state.paymentComplete) { return <div>Payment Complete!</div>; } else { return (<form onSubmit={this.onSubmit} > <span>{ this.state.paymentError }</span><br /> <input type="text" data-stripe="number" placeholder="credit card number" /><br /> <input type="text" data-stripe="exp-month" placeholder="expiration month" /><br /> <input type="text" data-stripe="exp-year" placeholder="expiration year" /><br /> <input type="text" data-stripe="cvc" placeholder="cvc" /><br /> <input disabled={this.state.submitDisabled} type="submit" value="Purchase" /> </form>); } } }); module.exports = PaymentForm;
Depois que o Stripe.js é carregado, nosso componente de formulário de pagamento retorna um formulário com os campos de entrada obrigatórios. Adicionamos os atributos data-stripe necessários de acordo com a documentação do Stripe. O evento onSubmit do formulário invoca um manipulador em nosso componente que chama Stripe.createToken(). Se um erro for retornado, mostraremos isso aos nossos usuários definindo state.paymentError igual à mensagem de erro. Caso contrário, definimos que o pagamento foi concluído com this.paymentComplete, e esse também é o ponto em que passaríamos o token e as informações de compra necessárias ao nosso servidor com um módulo como o superagente.
Resumo
Como o senhor pode ver, não é muito difícil eliminar o Checkout.js para usar seu próprio formulário de pagamento com estilo personalizado. Ao transformar isso em um componente e carregar o Stripe.js dinamicamente, ele também mantém os recursos que devem ser carregados pelo cliente em um nível mínimo e permite que você coloque isso em qualquer lugar que precise concluir uma compra em seu aplicativo React;
Depois de configurar esse componente React padrão para interagir com o Stripe.js, você pode adicionar outros campos relacionados ao produto que o usuário está comprando ou até mesmo tornar a coleta de informações de cartão de crédito uma etapa contínua do seu processo de inscrição. Seus usuários nunca saberão que o senhor depende do Stripe para fazer isso.
O Checkout.js adiciona uma camada de segurança percebida ao mostrar a marca Stripe e reconhecer o tipo de cartão quando o usuário digita o número do cartão de crédito. Eu recomendaria que o usuário se esforçasse um pouco para mostrar pistas visuais de segurança ao criar seu próprio formulário. Por exemplo, esse seria um ótimo lugar para mostrar o emblema do seu certificado SSL da Comodo ou da Network Solutions. Para confortar ainda mais seus usuários, integre algo semelhante a react-credit-card seria um ótimo toque final. Esse componente detecta automaticamente o tipo de cartão de crédito e mostra o logotipo apropriado em um cartão de crédito gerado por CSS, juntamente com o próprio número do cartão de crédito.
Felizmente, a integração do Stripe em seu front-end é bastante simples – não há como ser muito mais complicado do que isso! O verdadeiro trabalho (e diversão!) começa no código do servidor, que pode se tornar complicado e cheio de bugs se o senhor estiver fazendo mais do que aceitar pagamentos únicos para usuários que não se repetem. Boa sorte em seus esforços de pagamento on-line com JavaScript e, se quiser participar de seus próprios projetos ou tiver comentários sobre como integrou o Stripe ao React, entre em contato ou comente! As cinco primeiras pessoas que deixarem um comentário sobre o que mais gostaram deste post ou da dica sobre React e tuitarem o artigo receberão uma cópia GRATUITA do meu livro: The Node.js Engineer’s Guide to Stripe! Basta me mencionar no tweet e eu lhe enviarei uma mensagem de texto com instruções sobre como solicitar sua cópia.

Sobre Scott Hasbrouck
Scott é um engenheiro de software de longa data, que adora compartilhar suas habilidades com outras pessoas por meio da escrita e da orientação. Como empreendedor em série, ele fundou três empresas como fundador técnico, levando uma delas a mais de um milhão de usuários. Ele está sempre buscando a próxima aventura por meio de caminhadas em lugares remotos, pilotando pequenos aviões e viajando.