Tarjeta de crédito con React
El proceso de pago es uno de los punto mas críticos de una aplicación, pues un mal diseño puede causar que el cliente desista de realizar la compra, y no por el mero diseño, si no que le puede generar una cierta inseguridad sobre si el sitio es seguro.
En este artículo analizaremos como crear un formulario de pago atractivo y dinámico que le de cierta seguridad a nuestros clientes, utilizando para ello es componte react-credit-cards, con un resultado como el siguiente:
Antes de comenzar de dejaré el repositorio en GitHub donde podrás descargar este ejemplo: https://github.com/Centripio/youtube-react-creditcard
También puedes ver este mismo ecuatorial en Youtube:
Básicamente lo que tenemos que hace es importar el componente Cards y los sus estilos correspondientes, tal y como podemos ver en las líneas 2 y 3, el siguiente paso es Renderizar el componente Cards con al menos 5 propiedad, number
donde ponemos el número de la tarjeta, name
donde ponemos el nombre del dueño de la tarjeta y los campo expiry
y cvc
para representar la fecha de vigencia y el código de seguridad respectivamente. Finalmente el campo focused
indica el nombre del campo de la tarjeta que tiene el foco.
import React, { useState } from 'react'
import Cards from 'react-credit-cards'
import 'react-credit-cards/es/styles-compiled.css'
<Cards
number={state.number}
name={state.name}
expiry={state.expiry}
cvc={state.cvc}
focused={state.focus}
/>
Ya con esto definido, solo queda crear el formulario para actualizar el estado y con ellos los datos de la tarjeta, para esto, vamos a crear un formulario como el siguiente:
<form>
<div className="form-group">
<label htmlFor="number">Número de la tarjeta</label>
<input
type="text"
name="number"
id="number"
maxLength="16"
className="form-control"
onChange={handleInputChange}
onFocus={handleFocusChange}
/>
</div>
<div className="form-group">
<label htmlFor="name">Nombre</label>
<input
type="text"
name="name"
id="name"
maxLength="30"
className="form-control"
onChange={handleInputChange}
onFocus={handleFocusChange}
/>
</div>
<div className="form-row">
<div className="form-group col-md-6">
<label htmlFor="expiry">Fecha de expiración</label>
<input
type="text"
name="expiry"
id="expiry"
maxLength="4"
className="form-control"
onChange={handleInputChange}
onFocus={handleFocusChange}
/>
</div>
<div className="form-group col-md-6">
<label htmlFor="cvc">CVC</label>
<input
type="text"
name="cvc"
id="cvc"
maxLength="4"
className="form-control"
onChange={handleInputChange}
onFocus={handleFocusChange}
/>
</div>
</div>
<button onClick={processPayment} type="button" className="btn btn-success btn-block btn-lg">Pagar</button>
</form>
Observa como cada input
tiene como name
el nombre de la propiedad que requiere el componente Cards
, además tiene los eventos handleInputChange
que actualiza el estado cada vez que capturamos actualizamos cada campo:
const handleInputChange = (e) => {
setState({
...state,
[e.target.name] : e.target.value
})
}
Observa que esta función utiliza la propiedad name
para determinar que input
fue el actualizado y cambiar esa misma propiedad en el estado.
Finalmente, tenemos la función handleFocusChange
que nos permite identificar que input
tiene el foco, y con eso animar la tarjeta de crédito para seleccionar el campo que estamos capturando:
const handleFocusChange = (e) => {
setState({
...state,
focus : e.target.name
})
}
Podrás ver nuevamente la importancia de la propiedad name
para actualizar la propiedad focus
del estado.
Finalmente, aquí puedes ver como se ve el componente terminado:
import React, { useState } from 'react'
import Cards from 'react-credit-cards'
import 'react-credit-cards/es/styles-compiled.css'
const PaymentForms = () => {
const [state, setState] = useState({
number: "",
name: "",
expiry: "",
cvc: "",
focus: ""
})
const handleInputChange = (e) => {
setState({
...state,
[e.target.name] : e.target.value
})
}
const handleFocusChange = (e) => {
setState({
...state,
focus : e.target.name
})
}
const processPayment = () => {
console.log("number => ", state.number)
console.log("name => ", state.name)
console.log("expiry => ", state.expiry)
console.log("cvc => ", state.cvc)
console.log(JSON.stringify(state))
}
return (
<div className="card">
<div className="card-body">
<Cards
number={state.number}
name={state.name}
expiry={state.expiry}
cvc={state.cvc}
focused={state.focus}
/>
<form>
<div className="form-group">
<label htmlFor="number">Número de la tarjeta</label>
<input
type="text"
name="number"
id="number"
maxLength="16"
className="form-control"
onChange={handleInputChange}
onFocus={handleFocusChange}
/>
</div>
<div className="form-group">
<label htmlFor="name">Nombre</label>
<input
type="text"
name="name"
id="name"
maxLength="30"
className="form-control"
onChange={handleInputChange}
onFocus={handleFocusChange}
/>
</div>
<div className="form-row">
<div className="form-group col-md-6">
<label htmlFor="expiry">Fecha de expiración</label>
<input
type="text"
name="expiry"
id="expiry"
maxLength="4"
className="form-control"
onChange={handleInputChange}
onFocus={handleFocusChange}
/>
</div>
<div className="form-group col-md-6">
<label htmlFor="cvc">CVC</label>
<input
type="text"
name="cvc"
id="cvc"
maxLength="4"
className="form-control"
onChange={handleInputChange}
onFocus={handleFocusChange}
/>
</div>
</div>
<button onClick={processPayment} type="button" className="btn btn-success btn-block btn-lg">Pagar</button>
</form>
</div>
</div>
)
}
export default PaymentForms
Si quieres aprender más de React, te invitamos a que te des una vuelta por nuestro curso Mastering React, donde aprenderás todo lo necesario para crear tus propias aplicaciones, incluyendo la conexión con un API REST.