Aceite pagamentos com cartão sem webhooks
Saiba como confirmar um pagamento com cartão no servidor e processar solicitações de autenticação de cartão.
Para ter mais opções de suporte e preparo para o futuro, use a integração padrão para pagamentos assíncronos.
Esta integração usa um único fluxo do servidor ao cliente para receber pagamentos, sem usar webhooks nem processar eventos offline. Apesar de parecer mais simples, ela é difícil de expandir quando sua empresa cresce e tem várias limitações:
- Só aceita cartões: será preciso programar seu código separadamente para aceitar ACH e formas de pagamento regionais populares.
- Risco de cobrança dupla: ao criar um novo PaymentIntent de forma sincronizada sempre que o cliente tenta pagar, você corre o risco de cobrar o cliente duas vezes. Siga as práticas recomendadas.
- Gerenciamento manual da autenticação: cartões com 3D Secure ou sujeitos a normas como a Autenticação Forte de Cliente exigem mais ações do cliente.
Se decidir usar esta integração, considere essas limitações. Caso contrário, use a integração padrão.
Configurar a StripeLado do servidorLado do cliente
Servidor
Esta integração exige que os endpoints do seu servidor se comuniquem com a API da Stripe. Use nossas bibliotecas oficiais para acessar a API da Stripe a partir do seu servidor:
Cliente
O SDK do React Native é de código aberto e totalmente documentado. Internamente, utiliza as SDKs de iOS nativo e Android. Para instalar o SDK do React Native da Stripe, execute um dos seguintes comandos no diretório do seu projeto (dependendo de qual gerenciador de pacotes você usa):
Em seguida, instale algumas outras dependências necessárias:
- Para iOS, vá até o diretório ios e execute
pod install
para garantir a instalação das dependências nativas necessárias. - Para Android, não há mais dependências para instalar.
Observação
Recomendamos seguir o guia oficial do TypeScript para adicionar suporte ao TypeScript.
Inicialização da Stripe
Para inicializar a Stripe no aplicativo React Native, insira sua tela de pagamento com o componente StripeProvider
ou use o método de inicialização initStripe
. Somente a chave da API publicável em publishableKey
é necessária. O exemplo a seguir mostra como inicializar a Stripe usando o componente StripeProvider
.
import { useState, useEffect } from 'react'; import { StripeProvider } from '@stripe/stripe-react-native'; function App() { const [publishableKey, setPublishableKey] = useState(''); const fetchPublishableKey = async () => { const key = await fetchKey(); // fetch key from your server here setPublishableKey(key); }; useEffect(() => { fetchPublishableKey(); }, []); return ( <StripeProvider publishableKey={publishableKey} merchantIdentifier="merchant.identifier" // required for Apple Pay urlScheme="your-url-scheme" // required for 3D Secure and bank redirects > {/* Your app code here */} </StripeProvider> ); }
Observação
Use suas chaves de API de teste enquanto testa e desenvolve, e as chaves de modo de produção quando publica seu aplicativo.
Crie sua página de checkoutLado do cliente
Colete dados do cartão com segurança no cliente usando CardField
, um componente de IU fornecido pelo SDK que coleta número do cartão, data de valide, CVC e código postal.
O CardField
executa validação e formatação em tempo real.
Adicione o componente CardField
à tela de pagamentos para coletar com segurança dados de cartão dos clientes. Use o retorno de chamada onCardChange
para examinar dados não confidenciais do cartão, como a bandeira, e verificar se os dados estão completos.
import { CardField, useStripe } from '@stripe/stripe-react-native'; function PaymentScreen() { // ... return ( <View> <CardField postalCodeEnabled={true} placeholders={{ number: '4242 4242 4242 4242', }} cardStyle={{ backgroundColor: '#FFFFFF', textColor: '#000000', }} style={{ width: '100%', height: 50, marginVertical: 30, }} onCardChange={(cardDetails) => { console.log('cardDetails', cardDetails); }} onFocus={(focusedField) => { console.log('focusField', focusedField); }} /> </View> ); }
Execute o aplicativo e verifique se a página de checkout mostra o componente CardField
.
Coletar dados do cartãoLado do cliente
Quando o cliente estiver pronto para fazer o checkout, crie um PaymentMethod com os detalhes coletados pelo componente CardField
do cartão.
import { CardField, useStripe } from '@stripe/stripe-react-native'; function PaymentScreen() { const { createPaymentMethod, handleNextAction } = useStripe(); const pay = () => { // Gather customer billing information (for example, email) const billingDetails: CreatePaymentMethod.BillingDetails = { email: 'email@stripe.com', phone: '+48888000888', addressCity: 'Houston', addressCountry: 'US', addressLine1: '1459 Circle Drive', addressLine2: 'Texas', addressPostalCode: '77063', }; // Create payment method const { paymentMethod, error } = await createPaymentMethod({ paymentMethodType: 'Card', paymentMethodData: { billingDetails, } }); }; // ... }
Envie o PaymentMethod ao seu servidorLado do cliente
Se o PaymentMethod for criado corretamente, envie o ID dele para o seu servidor.
// ... const pay = () => { // ... // Send the PaymentMethod to your server to create a PaymentIntent const response = await fetch(`/pay`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ paymentMethodId: paymentMethod.id }), }); const { error, requires_action, payment_intent_client_secret } = await response.json(); if (error) { // Error creating or confirming PaymentIntent Alert.alert('Error', paymentIntentError); return; } if (payment_intent_client_secret && !requires_action) { // Payment succeeded Alert.alert('Success', 'The payment was confirmed successfully!'); } if (payment_intent_client_secret && requires_action) { // ...continued below } }; // ...
Criar um PaymentIntentLado do servidor
Configure um endpoint no seu servidor para receber a solicitação. Esse endpoint também será usado mais à frente, para gerenciar cartões que exijam mais uma etapa de autenticação.
Crie um novo PaymentIntent com o ID do PaymentMethod criado no cliente. Você pode confirmar o PaymentIntent definindo a propriedade confirm como verdadeira quando o PaymentIntent for criado ou invocando confirm após a criação. Também permitimos autorização e captura separadas para pagamentos com cartão.
Se o pagamento exigir ações adicionais, como autenticação do 3D Secure, o status do PaymentIntent será definido como requires_
. Se o pagamento falhar, o status será definido novamente como requires_
e você deverá mostrar um erro ao usuário. Se o pagamento não exigir autenticação adicional, uma cobrança será criada e o status do PaymentIntent será definido como succeeded
.
Observação
Nas versões do API anteriores a 2019-02-11, requires_
aparece como requires_
e requires_
aparece como requires_
.
Para salvar o cartão e poder reutilizá-lo depois, crie um Customer para armazenar o PaymentMethod e insira os seguintes parâmetros ao criar o PaymentIntent:
- cliente. Configurado com o ID do Cliente.
- setup_future_usage. Definido como
off_
para que a Stripe informe que você pretende usar este PaymentMethod para pagamentos fora da sessão, sem a presença do cliente. Esta configuração salva o PaymentMethod no Customer depois da confirmação do PaymentIntent e de todas as outras ações obrigatórias para o usuário. Veja o exemplo de código de salvar cartões depois de um pagamento para saber mais.session
Gerenciar outras açõesLado do cliente
Os pagamentos costumam ser finalizados após você confirmá-los no servidor, na etapa 4. No entanto, alguns fluxos de pagamento exigem mais alguma ação do cliente, como autenticação com 3D Secure.
Para os casos que exigem outras ações, o status do PaymentIntent é requires_
. No cliente, passe o segredo do cliente do PaymentIntent para handleNextAction
. O gerenciador nativo apresenta uma visualização e orienta o cliente pelo fluxo de autenticação. Depois de gerenciar as ações necessárias no cliente, o status do PaymentIntent muda para requires_
. Isso permite que sua integração execute o pedido no seu backend e retorne o resultado da execução para o cliente.
Envie o ID do PaymentIntent para seu backend e confirme novamente em até uma hora para finalizar o pagamento. Caso contrário, a tentativa de pagamento falha e o status do SetupIntent volta a ser requires_
.
// ... const pay = () => { // ... // If PaymentIntent requires action, call handleNextAction if (payment_intent_client_secret && requires_action) { const { error, paymentIntent } = await handleNextAction(payment_intent_client_secret); if (error) { Alert.alert(`Error code: ${error.code}`, error.message); } else if (paymentIntent) { if ( paymentIntent.status === PaymentIntents.Status.RequiresConfirmation ) { // Confirm the PaymentIntent again on your server const response = await fetch(`/pay`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ payment_intent_id: paymentIntent.id }), }); const { error, success } = await response.json(); if (error) { // Error during confirming Intent Alert.alert('Error', error); } else if (success) { Alert.alert('Success', 'The payment was confirmed successfully!'); } } else { // Payment succedeed Alert.alert('Success', 'The payment was confirmed successfully!'); } } } }; // ...
Confirmar o PaymentIntent novamenteLado do servidor
Esse código só é executado quando um pagamento exige autenticação adicional, assim como no gerenciamento da etapa anterior. O código em si não é opcional, porque qualquer pagamento pode exigir essa etapa extra.
Com o mesmo endpoint que você configurou acima, confirme o PaymentIntent mais uma vez para finalizar o pagamento e executar o pedido. Esta confirmação precisa acontecer no máximo uma hora após a tentativa de pagamento. Do contrário, o pagamento falha e volta ao status requires_
.
Testar a integração
Vários cartões de teste estão disponíveis para você usar em uma área restrita para assegurar que essa integração esteja pronta. Use-os com qualquer CVC e uma data de validade no futuro.
Número | Descrição |
---|---|
Finaliza e processa o pagamento imediatamente. | |
Requer autenticação. A Stripe abre uma janela solicitando que o cliente faça a autenticação. | |
Sempre falha, com o código de recusa insufficient_ . |
Veja a lista completa de cartões de teste em nosso guia de testes.