In my Raspberry Pi Photo booth application using Pi booth, PayPal payment is initiated through a QR code. Upon successful payment, however, I am redirected to a non-existent Webpage. This prevents the system from confirming the payment and showing the next step in the process — a Wi-Fi connection QR code. The same PayPal payment flow works correctly in a standalone GUI program where the payment completion closes the window without errors. Could this be related to the integration with Pi booth or the PayPal redirection settings?
This ist my stand alone code:
# -*- coding: utf-8 -*-
import qrcode
from PIL import Image
from io import BytesIO
import PySimpleGUI as sg
import requests
import threading
from flask import Flask, request, redirect, jsonify
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# Flask app für PayPal und GUI-Benachrichtigung
app = Flask(__name__)
# PayPal-Konfiguration
PAYPAL_CLIENT_ID = 'covered-for-paypal-community'
PAYPAL_SECRET = 'covered-for-paypal-community'
payment_successful = threading.Event()
def generate_qr(data):
qr = qrcode.QRCode(version=1, box_size=10, border=5)
qr.add_data(data)
qr.make(fit=True)
img = qr.make_image(fill='black', back_color='white')
return img
def create_qr_code():
if response.status_code == 200:
return generate_qr(response.url)
('/payment-success', methods=['POST'])
def payment_success():
payment_successful.set()
return jsonify({"status": "received"}), 200
def get_access_token():
response = requests.post(
PAYPAL_OAUTH_URL,
headers={'Accept': 'application/json', 'Accept-Language': 'de_DE'},
data={'grant_type': 'client_credentials'},
auth=(PAYPAL_CLIENT_ID, PAYPAL_SECRET)
)
return response.json()['access_token']
def create_payment():
access_token = get_access_token()
headers = {'Content-Type': 'application/json', 'Authorization': f'Bearer {access_token}'}
payment_data = {
"intent": "sale",
"redirect_urls": {
},
"payer": {"payment_method": "paypal"},
"transactions": [{
"amount": {"total": "0.50", "currency": "EUR"},
"description": "This is the payment transaction description."
}]
}
response = requests.post(PAYPAL_PAYMENT_URL, json=payment_data, headers=headers)
return response.json()
('/create-payment')
def create_payment_route():
payment = create_payment()
for link in payment['links']:
if link['rel'] == 'approval_url':
approval_url = link['href']
return redirect(approval_url)
return 'Error creating payment'
('/success')
def success():
payment_id = request.args.get('paymentId')
payer_id = request.args.get('PayerID')
execute_payment(payment_id, payer_id)
token = request.args.get('token')
notify_gui_payment_success()
def execute_payment(payment_id, payer_id):
access_token = get_access_token()
headers = {'Content-Type': 'application/json', 'Authorization': f'Bearer {access_token}'}
data = {"payer_id": payer_id}
response = requests.post(url, json=data, headers=headers)
return response.json()
def notify_gui_payment_success():
try:
response = requests.post(gui_notification_url, json={"status": "success"}, verify=False)
response.raise_for_status()
except requests.exceptions.RequestException as e:
print(f"Error notifying GUI: {e}")
('/cancel')
def cancel():
return "Zahlung abgebrochen"
# GUI
def start_gui():
layout = [[sg.Text("PayPal Payment")], [sg.Image(key='-QR-')]]
window = sg.Window("PayPal QR Payment", layout, finalize=True)
img = create_qr_code()
bio = BytesIO()
img.save(bio, format='PNG')
window['-QR-'].update(data=bio.getvalue())
while True:
event, values = window.read(timeout=100)
if event == sg.WIN_CLOSED:
break
if payment_successful.is_set():
window.close()
break
window.close()
# Starte Flask-Apps in separaten Threads
if __name__ == "__main__":
threading.Thread(target=lambda: app.run(host='0.0.0.0', port=443, use_reloader=False, ssl_context=('/home/Desktop/ssl/cert.crt', '/home/Desktop/ssl/key.pem'))).start()
threading.Thread(target=lambda: app.run(host='127.0.0.1', port=5000, use_reloader=False)).start()
start_gui()
The above code does work!!
But this code, involving pibooth with the same logik as the above code does not work:
import os
import shutil
import PySimpleGUI as sg
import qrcode
import pibooth
import subprocess
import tkinter as tk
import time
import requests
import threading
from flask import Flask, request, redirect, jsonify
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# Flask app für PayPal und GUI-Benachrichtigung
app = Flask(__name__)
PAYPAL_CLIENT_ID = 'covered-for-paypal-community'
PAYPAL_SECRET = 'covered-for-paypal-community'
payment_successful = threading.Event()
# Funktionen für die Zahlung
# 1. Token von PayPal holen
def get_access_token():
response = requests.post(
PAYPAL_OAUTH_URL,
headers={
'Accept': 'application/json',
'Accept-Language': 'de_DE'
},
data={
'grant_type': 'client_credentials'
},
auth=(PAYPAL_CLIENT_ID, PAYPAL_SECRET)
)
# Füge diese Zeilen hinzu, um die Antwort zu überprüfen
#print("Response Status Code:", response.status_code)
#print("Response Text:", response.text)
#response.raise_for_status()
return response.json()['access_token']
# 2. Zahlung erstellen
def create_payment():
access_token = get_access_token()
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {access_token}'
}
payment_data = {
"intent": "sale",
"redirect_urls": {
},
"payer": {
"payment_method": "paypal"
},
"transactions": [{
"amount": {
"total": "0.50",
"currency": "EUR"
},
"description": "Spenden Sie 50 Cent, um Ihr Bild herunterzuladen :)"
}]
}
response = requests.post(PAYPAL_PAYMENT_URL, json=payment_data, headers=headers)
return response.json()
('/payment-success', methods=['POST'])
def payment_success():
payment_successful.set()
return jsonify({"status": "received"}), 200
('/success')
def success():
payment_id = request.args.get('paymentId')
payer_id = request.args.get('PayerID')
execute_payment(payment_id, payer_id)
#token = request.args.get('token')
notify_gui_payment_success()
payment_successful.set()
return jsonify({"status": "Payment successful"})
# 3. Zahlung abschließen
def execute_payment(payment_id, payer_id):
access_token = get_access_token()
headers = {'Content-Type': 'application/json', 'Authorization': f'Bearer {access_token}'}
data = {"payer_id": payer_id}
response = requests.post(url, json=data, headers=headers)
return response.json()
# 4. Benachrichtige GUI bei erfolgreicher Zahlung
def notify_gui_payment_success():
try:
response = requests.post(gui_notification_url, json={"status": "success"}, verify=False)
response.raise_for_status()
except requests.exceptions.RequestException as e:
print(f"Error notifying GUI: {e}")
('/cancel')
def cancel():
return "Zahlung abgebrochen"
# Pibooth-Funktionen
def get_directory_content(folder_path):
if os.path.isdir(folder_path):
contents = os.listdir(folder_path)
jpg_files = [item for item in contents if item.lower().endswith('.jpg')]
for jpg_file in jpg_files:
return jpg_file
return None
def delete_folder_content(folder_path):
if os.path.exists(folder_path):
for file_name in os.listdir(folder_path):
file_path = os.path.join(folder_path, file_name)
if os.path.isfile(file_path):
os.unlink(file_path)
elif os.path.isdir(file_path):
shutil.rmtree(file_path)
class QRCodePopup:
def __init__(self, link):
self.link = link
self.show_payment_popup()
def show_payment_popup(self):
layout = [
[sg.Text("Möchten Sie 50 Cent spenden, um Ihr Bild herunterzuladen?", font=("Amatic Bold", 20))],
[sg.Image(key='-QR-')],
[sg.Button("NEIN DANKE", key="CLOSE", font=("Helvetica", 20))]
]
window = sg.Window("Zahlung", layout, finalize=True)
# Generiere den QR-Code für die Zahlung
payment_info = create_payment()
approval_url = next(link['href'] for link in payment_info['links'] if link['rel'] == 'approval_url')
qr_code_filename = self.generate_qr_code(approval_url)
window['-QR-'].update(filename=qr_code_filename)
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, "CLOSE"):
break
if payment_successful.is_set():
window.close()
self.show_download_popup()
window.close()
def show_download_popup(self):
layout = [
[sg.Text("Zahlung erfolgreich! Hier ist Ihr Download-Link:", font=("Amatic Bold", 20))],
[sg.Button("Download Bild", key="DOWNLOAD", font=("Helvetica", 20))],
[sg.Button("Schließen", key="CLOSE", font=("Helvetica", 20))]
]
window = sg.Window("Download", layout, finalize=True)
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, "CLOSE"):
break
if event == "DOWNLOAD":
# Logik zum Herunterladen des Bildes
sg.popup("Bild wird heruntergeladen...")
window.close()
def generate_qr_code(self, link, filename="qrcode.png"):
qr = qrcode.QRCode(version=1, box_size=10, border=4)
qr.add_data(link)
qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white")
img.save(filename)
return filename
def state_finish_do():
folder_path = "covered-for-paypal-community"
filename = get_directory_content(folder_path)
if filename:
QRCodePopup(link)
pibooth.hookimpl
def state_wait_enter():
folder_path = "covered-for-paypal-community"
delete_folder_content(folder_path)
if __name__ == "__main__":
threading.Thread(target=lambda: app.run(host='0.0.0.0', port=443, use_reloader=False, ssl_context=('/home/Desktop/ssl/cert.crt', '/home/Desktop/ssl/key.pem'))).start()
threading.Thread(target=lambda: app.run(host='0.0.0.0', port=5000, use_reloader=False)).start()
PLEASE ITS VERY IMPORTANT AND I NEED HELP ASAP!
I am thankfull for every answer and help! 🙂
Have a nice day!