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

    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.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *