pmaxNotify / app.py
Midnightar's picture
Update app.py
ec76674 verified
from flask import Flask, request, jsonify
import base64, hashlib, hmac, rsa
app = Flask(__name__)
# βš™οΈ Replace this with your real PayerMax private key (PEM string)
PRIVATE_KEY = """-----BEGIN RSA PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCDS2Bp66DKBHgW
CYs9ujP8N0Y60HDRcKmhApoCCI3qK4UE8KuaI/bobAbFr4f7bIU3WUnjtiuP1OUh
udr5ywdOZ76e6fxCAEJ/TJWtywDvclzqrVjRfe8F3mzF7/1yK0H/WY9IWHMO1sRV
WhbNBNYFQ7sLWysJaslD6peZF/vM+N5270nL8e+0p8S18+INFK9Gk5EW8BYLXD8
q28T5L74oL48dgkkLpy1EFDqhmEAJhZQPDpI5VFD7NSs5D0eU+AIYk9qsBX+A7qy
4O/U6SpL/JnaE6uLiQBc3zj4ZWtgw52eAx4fQ7cJgbzwsSbCHScvW0cgpiCZ1+B1
RdeBX9S3lAgMBAAECggEAClZc+Pn8ZuuDKPkHZYzLmwgfF3Jh75uXP34c8hwKUG2
sw37PhAtg3VvkDJyNcFZTBtCY6LznISP6BnXDr/c0VBAHCiwSGIA8vBkjj9Nz92Z
hunh7jcMElsm0dsE2i06sm5ZJmcCdDoYKX04AjZPb5f43M+WxtcQapKZL2VnyEWl
Jj3iui/ixoLiCXTBCvRAu2WWpKC3YELxFZ7yx24PKOlBcmUOHea/b88eBcSkcaOQ
XiU+i/jfJF/qOA2e/0h5mm9tLnXA2leIzscLylRjFsPownEr1T2+J3e+q+ygC5m4
JiEZcASr46hDDC9ReXsKXXxqAQezDyvpFvOkkXL7PAQKBgQDZlDi+pSD7HzBKcrk
Lil7jkBS8s9aOoO6QjvArnqN/SH1ThokgBaJF7kZC9vFOT09ZXSeCiBewbcavSXr
8ydDjV8SsgSk8wkmjDsQlOpXlzeE3H4fDS7lf/YLR+T5tvQZbgSxlG+0tQx+DcJz
vPMngc+51CVStzYITdXked3z+3QKBgQCaep09hoGx1aiKQLfdZAEDM0uAv6B2a2d
shmIxWw+7MoUKSyjAYVbIMk8Y+RyMBZkJNhxt3SegKtHO/S9R2Fa2QbUC3nc/qfe
DtdbaUOdXYBxJymtg9SUDjsIMusDUGu1aRXczzBK8jfKX9aaxQoOVkmxJYXC0/9/
5oIINZHrGqQKBgQDHfD1WleGaPGszJuH/8bq0G6rXpG8IUAbKpTMQWx9+GMFHLmd
U47V3NlJXHT/6035l6aHK7OoDSXLLzawkTwjlF9hrbPSZD20iQeyWUZOToeJmftM
jvK7WkoE58LJLPO6yQMmqXiNjx1ICWeKY+fwBfWlZBtgLjgs/ugn1ZApHRQKBgHH
yvAXkL8rTxYyljHq8B5sqvSjtMRnow9NjlQ6/Eu2MqGIdaqPtqSvnID1Vk98dSfN
nfLT1iwM0UqsSS1Nd9yhdc334R5Iod7Ep8p/7SYpEFNnBfE96xKDJLw5gu1g5vJb
34qPMho2bTzUUOK9MVu9/oGzIeXCpxbbG1Oe4FHBxAoGATTFW0o6ZILHqrquBbzm
ze9xf2dwPk4ixR4vfra64TdV1iISkJU0tBCO3VFxvlnaVXi+QsXZayKfdYj0MXLE
0GucYWVKgwA84NsgJA8JeOifriooIAX4ZqHFIG9OyO4VBz2iOCWUzanYGeBMxA4D
xO3lVx0gqIZWOjCqjqBKPG6U=
-----END RSA PRIVATE KEY-----"""
# βœ… 1. PayerMax callback endpoint
@app.route("/payermax", methods=["POST", "GET"])
def payermax_notify():
try:
print("βœ… PayerMax callback received")
data = request.get_json(force=True, silent=True)
print("🧾 Data:", data)
return "success", 200
except Exception as e:
print("πŸ”₯ Error in PayerMax callback:", str(e))
return "success", 200
# βœ… 2. FlutterFlow test endpoint
@app.route("/test", methods=["POST"])
def test_endpoint():
try:
data = request.get_json(force=True, silent=True)
print("πŸ§ͺ FlutterFlow test data:", data)
return jsonify({
"status": "ok",
"message": "Received test data successfully!",
"echo": data
}), 200
except Exception as e:
print("πŸ”₯ Error in test endpoint:", str(e))
return jsonify({"status": "error", "message": str(e)}), 500
# βœ… 3. Signature generator endpoint
@app.route("/sign", methods=["POST"])
def sign_payload():
"""
Generate RSA-SHA256 signature for a given string payload.
Body: { "payload": "string-to-sign" }
Returns: { "sign": "base64_signature" }
"""
try:
import base64
from Crypto.PublicKey import RSA
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256
data = request.get_json(force=True)
payload = data.get("payload", "")
if not payload:
return jsonify({"error": "Missing 'payload' field"}), 400
# Load your PEM private key
private_key = RSA.import_key(PRIVATE_KEY)
# Compute SHA256 hash of the exact payload string
h = SHA256.new(payload.encode('utf-8'))
# Sign it
signature = pkcs1_15.new(private_key).sign(h)
# Return base64-encoded signature as 'sign' (what your custom action expects)
signature_b64 = base64.b64encode(signature).decode('utf-8')
return jsonify({"sign": signature_b64}), 200
except Exception as e:
print("πŸ”₯ Error generating signature:", str(e))
return jsonify({"error": str(e)}), 500
if __name__ == "__main__":
app.run(host="0.0.0.0", port=7860)