I am trying to take credit card transactions using the square python API. I am using flask. When I use the Github example code that uses fastapi (connect-api-examples/connect-examples/v2/python_payment at master · square/connect-api-examples · GitHub) it works fine. But when I convert this to use flask vs fastapi, i get the payment request form but nothing happens on submit. In vscode I have the following error after typing in a sandbox credit card that works using the github code:
TypeError: create_payment() missing 1 required positional argument: 'payment'
I assumed it was a JS error since JS likely wasnt passing the parameters required for the payment class and I do indeed have the following JS error:
square.js:3 POST http://localhost:5000/process-payment 500 (INTERNAL SERVER ERROR)
and
square.js:3 Error: SyntaxError: Unexpected token '<', "<!doctype "... is not valid JSON
I have validated that my config.ini entries all work. I have validated that all libraries are correctly installed and referenced. I have validated that the values are properly getting passed to the HTML view (ie. Application_id, Location_id, Account_currency, account_country, UUID, and Payment_form_url). I am using the sandbox app_id, access token, and URL correcly. Same values work for the github example just not my flask. I have put the relevant code below. Could really use some help.
I include both the python code and the HTML view code below
Python code:
from flask import Flask, session, render_template, jsonify, request, redirect, url_for, json,
send_file
from square.client import Client
import configparser
from pydantic import BaseModel
import uuid
from square.http.auth.o_auth_2 import BearerAuthCredentials
app = Flask(__name__, static_url_path='/static')
wsgi_app = app.wsgi_app
app.config['SECRET_KEY'] = "keyremoved"
app.config.update(SESSION_COOKIE_NAME="cookienameremoved")
class Payment(BaseModel):
token: str
idempotencyKey: str
# successfully reading environment, app_id, and access_token from config file
config = configparser.ConfigParser()
config.read("square_config.ini")
# Retrieve credentials based on is_prod
CONFIG_TYPE = config.get("DEFAULT", "environment").upper()
PAYMENT_FORM_URL = (
"https://web.squarecdn.com/v1/square.js"
if CONFIG_TYPE == "PRODUCTION"
else "https://sandbox.web.squarecdn.com/v1/square.js"
)
APPLICATION_ID = config.get(CONFIG_TYPE, "square_application_id")
LOCATION_ID = config.get(CONFIG_TYPE, "square_location_id")
ACCESS_TOKEN = config.get(CONFIG_TYPE, "square_access_token")
bearer_auth_credential = BearerAuthCredentials(
access_token=ACCESS_TOKEN
)
client = Client(
bearer_auth_credentials=bearer_auth_credential,
environment=config.get("DEFAULT", "environment"),
user_agent_detail="hdh_app_python_payment",
)
location = client.locations.retrieve_location(location_id=LOCATION_ID).body["location"]
ACCOUNT_CURRENCY = location["currency"]
ACCOUNT_COUNTRY = location["country"]
@app.route("/")
def index():
uuidx = str(uuid.uuid4())
return render_template('square.html', PAYMENT_FORM_URL=PAYMENT_FORM_URL, APPLICATION_ID=APPLICATION_ID, LOCATION_ID=LOCATION_ID, ACCOUNT_CURRENCY=ACCOUNT_CURRENCY, ACCOUNT_COUNTRY=ACCOUNT_COUNTRY, uuidx=uuidx)
@app.post("/process-payment")
def create_payment(payment: Payment):
create_payment_response = client.payments.create_payment(
body={
"source_id": payment.token,
"idempotency_key": payment.idempotencyKey,
"amount_money": {
"amount": 100, # $1.00 charge
"currency": ACCOUNT_CURRENCY,
},
}
)
if create_payment_response.is_success():
print('success')
return create_payment_response.body
elif create_payment_response.is_error():
print('failed')
return create_payment_response
if __name__ == '__main__':
app.run(debug=True, port=5000)
HTML View Code:
Make Payment <!-- link to the Web SDK library -->
<script type="text/javascript" src={{PAYMENT_FORM_URL}}></script>
<script type="application/javascript">
window.applicationId = '{{APPLICATION_ID}}';
window.locationId = '{{LOCATION_ID}}';
window.currency = '{{ACCOUNT_CURRENCY}}';
window.country = '{{ACCOUNT_COUNTRY}}';
window.idempotencyKey = '{{uuidx}}';
</script>
<!-- link to the custom styles for Web SDK -->
<link rel='stylesheet', href='/static/css/sq-payment.css' />
<link rel='stylesheet', href='/static/css/style.css' />
</head>
<body>
<form class="payment-form" id="fast-checkout">
<div class="wrapper">
<div id="apple-pay-button" alt="apple-pay" type="button"></div>
<div id="google-pay-button" alt="google-pay" type="button"></div>
<div class="border">
<span>OR</span>
</div>
<div id="card-container"></div>
<button id="card-button" type="button">
Pay with Card
</button>
<span id="payment-flow-message">
</div>
</form>
<script type="text/javascript" src="/static/js/sq-ach.js"></script>
<script type="text/javascript" src="/static/js/sq-apple-pay.js"></script>
<script type="text/javascript" src="/static/js/sq-google-pay.js"></script>
<script type="text/javascript" src="/static/js/sq-card-pay.js"></script>
</body>
<!-- link to the local Web SDK initialization -->
<script type="text/javascript" src="/static/js/sq-payment-flow.js"></script>