#!/usr/bin/env python3 """Python 3, standard library. Dry run by default; --send creates ONE real order.""" import hashlib import json import os import secrets import sys import time import urllib.request from pathlib import Path URL = "https://transaction.hisspay.com/transaction/payin/v1/apply" def sign(body, app_id, secret, timestamp, nonce): headers = {"appId": app_id, "timestamp": timestamp, "nonce": nonce} values = {**body, **headers} if any(not isinstance(v, str) for v in values.values()): raise ValueError("Use string top-level fields; cardExtra must be JSON text") canonical = "&".join(k + "=" + values[k] for k in sorted(values)) headers["sign"] = hashlib.sha256((canonical + secret).encode("utf-8")).hexdigest() return headers class NoRedirect(urllib.request.HTTPRedirectHandler): def redirect_request(self, *args, **kwargs): return None def main(): if len(sys.argv) not in (2, 3) or (len(sys.argv) == 3 and sys.argv[2] != "--send"): raise SystemExit("Usage: python3 wallet_request.py request.json [--send]") body = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8")) if len(sys.argv) == 2: print(json.dumps(body, ensure_ascii=False, indent=2)) return # Replace ALL example customer data, URLs and order number before --send. if body.get("clientIp") == "" or "REPLACE_UNIQUE" in body.get("merchantOrderNo", ""): raise SystemExit("Replace example payer IP and unique order number first") headers = sign(body, os.environ["HISSPAY_APP_ID"], os.environ["HISSPAY_APP_SECRET"], str(int(time.time() * 1000)), secrets.token_hex(16)) headers["Content-Type"] = "application/json" request = urllib.request.Request(URL, data=json.dumps(body, ensure_ascii=False, separators=(",", ":")).encode("utf-8"), headers=headers, method="POST") # No automatic application retry or redirects. On timeout, query the original order. with urllib.request.build_opener(NoRedirect).open(request, timeout=30) as response: print(response.read().decode("utf-8")) if __name__ == "__main__": main()