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.