DEV Community

Cover image for Meses sin Intereses en Stripe con Python y React parte 2
Leonardo Alonso
Leonardo Alonso

Posted on • Edited on

Meses sin Intereses en Stripe con Python y React parte 2

En el post pasado iniciamos creando nuestra estructura de archivos y directorios para nuestro formulario de pago con stripe usando React y Flask.

Ya con todo eso listo podemos iniciar a crear los componentes de React que necesitaremos para procesar los pagos.

Instalando la librería de react para stripe

Esto es muy simple lo único que debemos hacer es:

npm install --save @stripe/react-stripe-js @stripe/stripe-js

y listo, ya se actualizo nuestro package.json y se instalo la librería.

Agregando Bootstrap (para que no se vea tan feo)

Bootstrap es un framework de frontend con el propósito de estilizar nuestras aplicaciones o sitios web.

Existen muchas maneras de agregarlo a un proyecto en React pero la más simple y la que vamos a utilizar es agregando el CDN a el index de nuestra aplicación.

Pero no lo vamos a agregar al index.js si no que dentro de la carpeta public encontraremos un archivo de nombre index.html y es en este dónde agregaremos el CDN de (bootstrap)[https://getbootstrap.com/docs/4.5/getting-started/introduction/]

Al igual que cualquier archivo css este va dentro de un tag <link> y dentro del <head> de la pagina quedando algo como esto.

Alt Text

Modificando la estructura de archivos

Cuando creamos un nuevo proyecto de react usando create-react-app este nos da una estructura de archivos inicial, para este caso vamos a modificar un poco esta estructura.

  • Ir a la carpeta src
  • Dejar únicamente el archivo index.js

Cuando eliminemos estos archivos y tratemos de iniciar el proyecto con npm start seguramente tendremos varios errores y estos serán causados por las importaciones de archivos que ya no existen por lo que vamos a modificar ese archivo index.js de la siguiente manera.

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App'

ReactDOM.render(<App/>, document.getElementById('root'));
Enter fullscreen mode Exit fullscreen mode

Creando los componentes

Ahora aun tendremos un error de importación por que para este punto aún no existe el componente App por lo que vamos a crearlo al mismo nivel que index.js

Alt Text

Para toda esta serie de tutoriales vamos a utilizar functional componets que es la forma en la que React nos dice que deberíamos trabajar, si alguno de ustedes esta acostumbrado a utilizar ClassComponents es muy fácil migrar de uno a otro.

Ahora si el componente App

// App.js

import React from 'react'
import { Elements } from '@stripe/react-stripe-js'
import { loadStripe } from '@stripe/stripe-js'

const App = () => {
    const stripePromice = loadStripe('stripe_public_key')

    return (
        <div className="container">
            <div className="row">
                <Elements stripe={stripePromice}>

                </Elements>
            </div>
        </div>
    )
}

export default App
Enter fullscreen mode Exit fullscreen mode

Ok.. todo se ve muy cool pero que estamos haciendo, bueno partiendo de la estructura fuente de un functional component lo que estamos haciendo es importar Elements de la librería de stripe la cual nos va a permitir utilizar los objetos Element de stripe en cualquier componente heredado.

Y la otra cosa que estamos haciendo es autenticandonos con nuestra clave publica de stripe esto con la función loadStripe la cual cargara de forma asíncrona al script de Stripe.js.

Esa autenticación se la pasamos como prop el componente Element y listo ya podemos utilizar stripe.

Creando el CardElement

Dentro de la carpeta src vamos a crear una nueva carpeta llamada components y dentro de esta crearemos un archivo llamado CheckoutForm.js y escribiremos lo siguiente:

// CheckoutForm.js
import React from 'react'
import CardSection from './CardSection'

const CheckoutForm = () => {
    return (
        <div className="col-lg-12">
            <form>
                <h1>Formulario de Pago</h1>
                <div className="form-group">
                    <CardSection/>
                </div>
                <button className="btn btn-primary">Pay</button>
            </form>
        </div>
    )
}

export default CheckoutForm
Enter fullscreen mode Exit fullscreen mode

Este componente nos va a servir para agregar todos los datos del formulario de pago que vallamos a necesitar, es decir nombre del cliente, email, etc... Todo lo que queremos saber del cliente y por supuesto los datos de su tarjeta para realizar el cobro.

En este caso únicamente estaré pidiendo los datos de la tarjeta, pero desde este componente es donde se pedirá toda la información del cliente.

Ahora en este punto no tenemos creado aun el componente CardSection por lo que vamos a hacerlo.

Dentro de la carpeta components vamos a crear un archivo llamado CardSection.js, dentro de este archivo escribimos lo sigueinte.

import React, { useState } from 'react'
import { CardElement } from '@stripe/react-stripe-js'
import '../css/stripe_form.css'

const  CardSection = () => {

    const [state, setState] = useState({
        'errorMessage': ''
    })

    const card_element_options = {
        style: {
            base: {
                color: "#32325d",
                fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
                fontSmoothing: "antialiased",
                fontSize: "16px",
                "::placeholder": {
                    color: "#aab7c4",
                },
            },
            invalid: {
                color: "#fa755a",
                iconColor: "#fa755a",
            },
        }
    }

    const handleOnChanage = (event) => {
        setState({errorMessage: ''})
        if (event.error) {
            setState({error: true, errorMessage:event.error.message})
        }
    }

    return (
        <>
            <CardElement options={card_element_options} onChange={handleOnChanage}/>
            <div className="card-errors">
            <p>{state.errorMessage}</p>
            </div>
        </>
    )
}

export default CardSection
Enter fullscreen mode Exit fullscreen mode

Muy bien vamos a la explicación.

En este componente estamos importando de stripe el componente CardElement.

Stripe nos proporciona muchos Elements para crear nuestro formulario de pago, pero el CardElement es uno de los mas utilices desde mi punto de vista por que engloba todos los datos de la tarjeta que necesitamos en un solo input evitando tener que hacer muchos clics o lo que sea, de todos modos aquí les dejo el resto de los elemento que nos provee stripe. https://stripe.com/docs/stripe-js

Ahora tambien estamos agregando algunas opciones de estilos por default al CardElement.

También estamos validando si existe algún error en los datos de la tarjeta haciendo uso del prop onChange del componente CardElement, para esta validación hacemos uso del hook de React useState de tal forma que cuando hay un error en el objeto event del componente CardElement actualizamos el state y lo renderizamos en el tag

Aquí les dejo la documentación de stripe en donde podremos ver todas las props que le podemos pasar a los elementos de stripe

https://stripe.com/docs/js/elements_object/create_element?type=card#elements_create-options

En este componente también agregamos algunos estilos por CSS, mismos que les dejare en el Repo del proyecto para no escribir todo el código aquí.

Ya con todos los componentes listos solo nos queda importar el componente CardForm dentro de App.

        <div className="container">
            <div className="row">
                <Elements stripe={stripePromice}>
                    {/* Load the checkout form */}
                    <CheckoutForm/>
                </Elements>
            </div>
        </div>
Enter fullscreen mode Exit fullscreen mode

y listo ya tenemos nuestro formulario.

Alt Text

Aun no acepta pagos, pero esto lo iremos haciendo en los siguientes post.

Les dejo el Repo del proyecto de React en donde podrán ver todo el código o clonarlo para verlo en uso en sus computadoras.

https://github.com/leonardoAlonso/StripeForm

Top comments (0)