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' PAYPAL_OAUTH_URL = 'https://api-m.sandbox.paypal.com/v1/oauth2/token' PAYPAL_PAYMENT_URL = 'https://api-m.sandbox.paypal.com/v1/payments/payment' gui_notification_url = "http://127.0.0.1:5000/payment-success" 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(): response = requests.get('http://127.0.0.1:5000/create-payment', verify=False) 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": { "return_url": "https://covered-for-paypal-community(its my IP4 Adress/Public IP)/success", "cancel_url": "https://covered-for-paypal-community(its my IP4 Adress/Public IP)/cancel" }, "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() return redirect(f"https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token={token}") def execute_payment(payment_id, payer_id): access_token = get_access_token() url = f'https://api-m.sandbox.paypal.com/v1/payments/payment/{payment_id}/execute' 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' PAYPAL_OAUTH_URL = 'https://api-m.sandbox.paypal.com/v1/oauth2/token' PAYPAL_PAYMENT_URL = 'https://api-m.sandbox.paypal.com/v1/payments/payment' gui_notification_url = "http://127.0.0.1:5000/payment-success" 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": { "return_url": "https://covered-for-paypal-community/success", "cancel_url": "https://covered-for-paypal-community/cancel" }, "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() #return redirect(f"https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token={token}") payment_successful.set() return jsonify({"status": "Payment successful"}) # 3. Zahlung abschließen def execute_payment(payment_id, payer_id): access_token = get_access_token() url = f'https://api-m.sandbox.paypal.com/v1/payments/payment/{payment_id}/execute' 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: link = "http://raspberrypi.local/pictures/" + 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!
... View more