Meses sin Intereses en Stripe con Python y React parte 4
Tags: python, flask, stripe, react
Published: 2020-12-03 00:33:13

En nuestro post anterior al fin terminamos nuestro formulario de pago del lado de React JS, en este post daremos inicio a la creación de nuestra pequeña api para aceptar los pagos utilizando flask.

# Instalando los paquetes

Antes de realizar cualquier instalación vamos a activar nuestro entorno virtual.

`source env/bin/activate`

Ahora si para instalar flask solo debemos de hacer: 

`pip install flask`

Y para instalar la librería de stripe hacemos:

`pip install stripe`

# Creando nuestra api

Esta será una api pequeña por lo que solo necesitaremos un archivo al que llamaremos api.py

Para validar que flask esta correctamente instalado vamos a escribir lo siguiente

```
import flask

app = flask.Flask(__name__)
app.config["DEBUG"] = True


@app.route('/', methods=["GET"])
def home():
    return "<h1> Flask API </h1>"

app.run()
```

Ahora hacemos `python api.py` lo cual iniciara el servidor de DEBUG de flask con el que podremos acceder a nuestro localhost en el puerto 5000 el cual es el puerto por defecto para flask, este puede ser cambiado dentro de los parámetros de la función `run()`.

Entonces si accedemos a 127.0.0.1:5000 veremos el mensaje que hemos colocado dentro de la función `home`.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/gc5hli5ifxfkne70d575.png)

Ahora, recordando un poco nuestra aplicacion de React esta apuntando a la siguiente ruta `api/acept_payment`, por lo que procederemos a crearla.

```
@app.route('/api/acept_payment', methods=['POST'])
def acept_payment():
    pass
```

Ahora vamos a iniciar nuestro proyecto de React y a reiniciar nuestro servidor de flask, al hacer la peticion tal cual la tenemos ahora en nuestra aplicación nos toparemos con un error relacionado a CORS, sobre este tema vamos a hablar mas en otro post de momento para solucionarlo haremos la siguiente modificación.

Vamos a instalar la libreria `flask-cors` haciendo `pip install flask-cors` y escribimos lo siguiente

```
from flask import Flask, request, jsonify
from flask_cors import CORS

app = Flask(__name__)
app.config["DEBUG"] = True
CORS(app)
```

Vale en principio pensaríamos que esto va a funcionar pero si hacemos la petición al backend nos vamos a topar con el siguiente error:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5zhz3kutabf3znhqg57b.png)

Y esto que significa? :confused: Bueno pues resulta que no podemos hacer peticiones a un servidor sin https.

Vale y eso como lo solucionamos? pues de inicio nos podemos crear un certificado autofirmado y esto lo vamos a hacer de la siguiente manera

` openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365
`

Completamos toda la información que nos solicita y listo ya solo nos queda agregarlo a nuestro proyecto en python

`app.run(ssl_context=('cert.pem', 'key.pem'))`

Ahora desde el navegador debemos entrar a nuestro localhost en el puesto 5000 o el que hayan configurado para el servidor de prueba de flask y darle permiso para que utilice nuestro certificado autofirmado.

Esta solución no debe ir NUNCA en producción, para producción o nos compramos los certificados o usamos letsencript o lo que sea pero jamás un autofirmado.

Ok, ahora si nuestra petición ha de funcionar como esperamos

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/pd39h67n3ifusy7mfzxv.png)

Muy bien ya podemos modificar nuestra api para aceptar el objeto json que enviamos desde react.

```
@app.route('/api/acept_payment', methods=['POST'])
def acept_payment():
    data = request.get_json()
    print(data)
    return {'ff':'ff'}
```

Con la función get_json() de request obtenemos todo lo que se envié por método POST en formato json y de momento regresamos un diccionario de prueba.

Con esto estamos listos ahora si para aceptar nuestro pago con Stripe, así que vamos a modificar nuestra api

```
from flask import Flask, request, jsonify
from flask_cors import CORS

import stripe

stripe.api_key = 'secret'

app = Flask(__name__)
app.config["DEBUG"] = True
CORS(app)


@app.route('/', methods=['GET'])
def home():
    return "<h1> Flask API </h1>"

@app.route('/api/acept_payment', methods=['POST'])
def acept_payment():
    data = request.get_json()
    payment = stripe.PaymentIntent.create(
        amount=2000,
        currency='mxn',
        payment_method=data['payment_method'],
        payment_method_types=["card"],
        off_session=True,
        confirm=True
    )
    print(payment)
    return payment

app.run(ssl_context=('cert.pem', 'key.pem'))
```

Con esto estamos haciendo uso de el api de stripe y mas en especifico de su api de `paymentIntents` entre los parámetros que estamos enviando esta el monto a cobrar, el tipo de cambio, el tipo de método de pago.

Mas en especifico el parámetro `off_session` significa que no estamos enviando un id para `customer` y `confirm` significa que queremos confirmar el pago, ahora para que `confirm` sea True `off_session` también debe ser True.

No hay que olvidar poner nuestro propia clave secreta en esta linea.

`stripe.api_key = 'secret'`

de lo contrario nada de esto va a funcionar.

Con esto ya estamos aceptando pagos con stripe solo queda ver si el pago realmente se realizo y eso lo podemos ver desde el dashboard de stripe.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/2tga91h088zpcgickwf6.png)

Aquí vemos nuestro pago confirmado pero... en el monto le pusimos que queríamos cobrar 2000 y el cargo que tenemos es solo por 20. Bueno esto se debe a que stripe toma el monto dos ceros antes, pero la solución para eso es que el valor que queremos cobrar los multipliquemos por 100 y listo.

```
@app.route('/api/acept_payment', methods=['POST'])
def acept_payment():
    data = request.get_json()
    amount = 2000
    payment = stripe.PaymentIntent.create(
        amount=amount*100,
        currency='mxn',
        payment_method=data['payment_method'],
        payment_method_types=["card"],
        off_session=True,
        confirm=True
    )
    print(payment)
    return payment
```

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/f1ht3jb97n6yxlmk02jm.png)

Ahora si todo esta bien y con eso vamos a concluir este POST que fue un poco mas largo que los anteriores pero con el propósito de mostrar las posibles complicaciones a las que nos vamos a enfrentar cuando trabajemos proyectos de este tipo, si aun así quedan dudas pueden usar los comentarios y tratare de responder a cada uno de ellos. Por ultimo les dejo los repositorios de cada proyecto y nos vemos en el siguiente post.

https://github.com/leonardoAlonso/StripeForm
https://github.com/leonardoAlonso/stripe-flask-api

# Happy Codding