Integración de Stripe con Java Spring para el procesamiento de pagos

I

Introducción

No es mentira que “todo se está volviendo digital”. Muchos productos nunca llegan a los estantes, sino que se venden en línea.

Con el creciente número de emprendedores, startups y ventas online, hoy en día un porcentaje muy alto de sitios web tiene un sistema de pago, ya sea una suscripción a un servicio o un pago único por un producto.

El manejo de las finanzas es un tema delicado, y crear su propia lógica para manejar los pagos puede parecer desagradable para muchos desarrolladores, especialmente si no tienen mucha experiencia previa con dichos sistemas.

Para nuestra ayuda vienen servicios como PayPal y Raya. Ambos servicios son excelentes y cada uno tiene sus pros y sus contras. Si bien PayPal ciertamente ha sido el más popular, Stripe ofrece más métodos de pago y tarifas más simples, aunque se necesita un día más para retirar fondos, aunque para muchos, esto no es realmente importante.

¿Qué es Stripe?

Stripe es un procesador de pagos para pequeñas y medianas empresas que ofrece varios productos dentro de su red: datos comerciales, detección de fraudes con Machine Learning, emisión de tarjetas, etc.

Como ocurre con muchos servicios útiles, Spring ofrece soporte para integrar la API Stripe e implementar la funcionalidad de pago en sus aplicaciones Spring.

Integración de Stripe con una aplicación Spring Boot

Cuenta Stripe

En primer lugar, para lidiar con la API de Stripe, necesitamos abrir una cuenta en Raya.

Abrir una cuenta es muy simple y lo único que necesita hacer es verificar su dirección de correo electrónico y número de teléfono. Aunque esto solo le proporcionará una cuenta de prueba mientras Stripe aprueba su aplicación, lo que puede tardar desde unos minutos hasta unos días.

Justo en el tablero, podrá encontrar las claves en vivo / de prueba para la API:

Estas claves serán utilizadas por nuestra aplicación Spring para acceder a la API. Por ahora, simplemente guardémoslos en el application.properties archivo:

STRIPE_PUBLIC_KEY = pk_test_abc123
STRIPE_SECRET_KEY = sk_test_abc123

Obviamente, hemos utilizado algunas claves falsas en este ejemplo, así que asegúrese de reemplazarlas con sus propias claves de prueba.

Aplicación Spring Boot

Como siempre, para nuestra aplicación Spring Boot, usaremos Spring Initializr para generar un proyecto inicial. Por ahora, solo necesitamos el spring-web-starter y spring-boot-starter-thymeleaf dependencias:

Desde el stripe-java la dependencia no está en la lista Spring Initializr, la agregaremos directamente a nuestro pom.xml archivo:

<dependency>
    <groupId>com.stripe</groupId>
    <artifactId>stripe-java</artifactId>
    <version>10.12.1</version>
</dependency>

Nuestra aplicación ofrecerá dos opciones para compradores potenciales:

  • Compra única: Pueden comprar un curso Pharos.sh por un pago único
  • Suscripción: Pueden inscribirse para un lugar en nuestra lista de correo electrónico, donde enviamos mini-cursos semanales (próximamente en un próximo artículo)

Además, enviaremos recibos por correo electrónico a nuestros clientes.

La API de Stripe

La API de Stripe funciona de forma sencilla. Acepta cuerpos de solicitud codificados en formularios y envía respuestas codificadas en JSON.

Para propósitos de prueba / aprendizaje, podemos usarlo en modo “prueba”, con claves de prueba. Estas transacciones en realidad no realizarán transacciones reales.

Puede verlos en el Panel de control de rayas:

Con la configuración de nuestra cuenta y nuestras claves en mente, incluso podríamos hacer una solicitud ahora mismo usando curl:

$ curl https://api.stripe.com/v1/charges 
  -u {SECRET_kEY}: 
  -d amount=999 
  -d currency=usd 
  -d description="Example charge" 
  -d source=tok_visa

Ejecutar esto nos daría una respuesta codificada en JSON:

{
  "id": "ch_1F3WU7DEYNNUvOkfbHegnPia",
  "object": "charge",
  "amount": 999,
  "amount_refunded": 0,
  "application": null,
  "application_fee": null,
  "application_fee_amount": null,
  ...
  ...
  ...
}

Y si revisamos nuestro tablero, recibimos $ 9.99 del cargo:

Ahora, creemos una aplicación que podrá enviar solicitudes de este tipo de una manera más amigable para los humanos al aceptar una tarjeta de crédito válida.

El flujo general de solicitudes de Stripe se parece a esto:

  • Interfaz: El front-end se utiliza para enviar datos de tarjetas de crédito codificados en formulario a Stripe
  • Raya: Stripe responde enviando un token dentro de la respuesta
  • Interfaz: El front-end se comunica con nuestro back-end proporcionando el token y la cantidad requerida para pagar
  • Back-end: Utiliza la clave privada (secreta) de Stripe, junto con el token, la cantidad y la moneda para procesar el pago

Por lo tanto, es lógico que comencemos con el front-end.

Interfaz

Stripe nos proporciona Stripe.js, su biblioteca esencial para crear flujos de pago. Junto a la biblioteca, nos proporciona Stripe Elements, que son elementos prediseñados que se utilizan para recopilar datos confidenciales del consumidor, como un número de tarjeta de crédito.

De esta manera, los datos confidenciales realmente no ingresan a nuestro propio sistema y Stripe se encarga de ellos en un iframe, haciéndolo seguro y fácil tanto para nosotros como para el usuario final.

Hay varios elementos que ofrecen para la recopilación rápida de información de pago:

Stripe agregará automáticamente el elemento Stripe preferido en su HTML, donde lo marque. Por ejemplo, para agregar el elemento de tarjeta:

<script src="https://js.stripe.com/v3/"></script>

<form action="/charge" method="post" id="payment-form">
  <div class="form-row">
    <label for="card-element">
      Credit or debit card
    </label>
    <div id="card-element">
      <!-- A Stripe Element will be inserted here. -->
    </div>

    <!-- Used to display form errors. -->
    <div id="card-errors" role="alert"></div>
  </div>

  <button>Submit Payment</button>
</form>

Nosotros usaremos checkout.js ya que es un elemento de uso muy común. Es un poco diferente a agregar el elemento de tarjeta:

<form action='/charge' method='POST' id='checkout-form' xmlns:th="http://www.w3.org/1999/xhtml">
    <input type="hidden" th:value="${amount/100}" name="amount" />
    <h1>Price:<span th:text="${amount/100}" /></h1>
    <script
            src="https://checkout.stripe.com/checkout.js"
            class="stripe-button"
            th:attr="data-key=${stripePublicKey},
         data-amount=${amount}"
            data-name="Pharos.sh Services"
            data-description='Product Checkout'
            data-image="http://www.Pharos.sh.com/assets/images/sa-java-dark.svg?v=b5a08453df"
            data-locale="auto"
            data-zip-code="false">
    </script>
</form>

En aras de la brevedad y la simplicidad, es solo una forma, que apunta a nuestro /charge punto final. No importa el Thymeleaf atributos por ahora, los cubriremos en la sección del controlador.

Por ahora, es importante tener en cuenta que simplemente estamos agregando el script a nuestra página, lo que resultará en el botón “Pagar con tarjeta”:

Al hacer clic en él, nos saludan con nuestra ventana de pago:

Controlador

Con el front-end, fuera del camino, centrémonos un poco en el lado del back-end. Al hacer clic en “Enviar” en la ventana de pago se enviará la información a Stripe, que devolverá un token que necesitamos para la autenticación. Definamos un simple PaymentController:

@Controller
public class PaymentController {
    // Reading the value from the application.properties file
    @Value("${STRIPE_PUBLIC_KEY}")
    private String stripePublicKey;

    @RequestMapping("/")
    public String home(Model model) {
        model.addAttribute("amount", 50 * 100); // In cents
        model.addAttribute("stripePublicKey", stripePublicKey);
        return "index";
    }
}

Lo que hacemos aquí es muy sencillo. Asignamos el STRIPE_PUBLIC_KEY value a una cadena para su uso posterior y agregarlo al modelo para que podamos usarlo en el front-end. En nuestro formulario anterior, estamos usando el amount y stripePublicKey para enviar una solicitud a Stripe, que genera una stripeToken para nosotros en respuesta.

Hagamos un punto final para la respuesta devuelta:

@Autowired
private StripeService stripeService;

@RequestMapping(value = "/charge", method = RequestMethod.POST)
public String chargeCard(HttpServletRequest request) throws Exception {
    String token = request.getParameter("stripeToken");
    Double amount = Double.parseDouble(request.getParameter("amount"));
    stripeService.chargeNewCard(token, amount);
    return "result";
}

De la respuesta, simplemente extraemos el stripeToken y el amount parámetros y pasarlos a nuestro servicio, que en realidad gestiona la comunicación con Stripe y el procesamiento de pagos.

Servicio

La capa de servicio nos presenta algunas clases nuevas:

@Service
public class StripeService {

    @Value("${STRIPE_SECRET_KEY}")
    private String API_SECRET_KEY;

    @Autowired
    public StripeService() {
        Stripe.apiKey = API_SECRET_KEY;
    }

    public Charge chargeNewCard(String token, double amount) throws Exception {
        Map<String, Object> chargeParams = new HashMap<String, Object>();
        chargeParams.put("amount", (int)(amount * 100));
        chargeParams.put("currency", "USD");
        chargeParams.put("source", token);
        Charge charge = Charge.create(chargeParams);
        return charge;
    }
}

Normalmente, una clase de servicio contendría muchos más métodos como getCustomer(), createCustomer(), chargeCustomerCard(), etc. Aunque, por ahora y en aras de la simplicidad, usemos este único método.

Aquí, estamos usando nuestra clave secreta. Mediante el Charge clase proporcionada por Stripe, establecemos los parámetros de cargo, como el monto y la moneda.

La cantidad se multiplica por 100 ya que Stripe se ocupa de la opción más pequeña cuando se trata de moneda, en este caso centavos. Para expresarlo en dólares, lo estamos multiplicando.

En este punto, podemos ejecutar la aplicación y probarla.

Ejecutando la Aplicación

Al ejecutar la aplicación, nuestra página de índice nos saluda:

Después de hacer clic en el botón, se nos solicita la ventana de pago. Para propósitos de prueba, puede usar un número de tarjeta de prueba, como 4242 4242 4242 4242:

Después de eso, nos saludan con la página de resultados y también podemos validar el pago en el panel:

Cuando desee transferir esto a una aplicación real que realmente cobre a las personas por un producto, simplemente cambie las claves de prueba y coloque las reales.

Envío de recibos por correo electrónico

Ahora, queremos enviar un correo electrónico con un recibo cada vez que alguien realiza una compra. Para hacer esto, en lugar de definir nuestra propia lógica, que sería redundante, Stripe envía correos electrónicos a los clientes una vez que sus pagos han sido aceptados o reembolsados.

Nota: La API de prueba no enviar confirmaciones / recibos por correo electrónico. Puedes leer más sobre esto Aquí.

Puede configurar los ajustes de recibo de Stripe en su panel de control. Si quieres más información sobre esto, echa un vistazo Documentación de Stripe.

Conclusión

Con el aumento de la dependencia y el pago en línea, lo más probable es que en algún momento su aplicación web tenga que manejar / procesar algunos pagos. Dado que es un tema delicado, es más fácil y seguro dejar que un procesador de terceros como Stripe o PayPal maneje la transacción real y actúe como un intermediario confiable.

En este artículo demostramos cómo integrar la API de Stripe en una aplicación Spring Boot y cómo cargar con éxito la tarjeta de un cliente.

 

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con tus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad