Skip to content

Python Example

Example: POST /payIn/orders/createAndPay, sign data is timestamp|nonce|rawBody.

python
import hmac
import hashlib
import base64
import time
import json

def sign(timestamp: str, nonce: str, body: str, secret: str) -> str:
    sign_data = f"{timestamp}|{nonce}|{body}"
    digest = hmac.new(secret.encode("utf-8"),
                      sign_data.encode("utf-8"),
                      hashlib.sha256).digest()
    return base64.b64encode(digest).decode("utf-8")

body = json.dumps({
    "merchantOrderNo": "M202412220001",
    "amount": "100.00",
    "currency": "USD",
    "methodCode": "INTERNATIONAL_CARD",
    "methodData": {
        "cardNumber": "4111111111111111",
        "expiryMonth": "12",
        "expiryYear": "27",
        "securityCode": "123"
    }
}, separators=(",", ":"))

timestamp = str(int(time.time() * 1000))
nonce = "b2b2f3b6a6f24a4ba3dcd0e777c9a888"
signature = sign(timestamp, nonce, body, "sk_test_9f3b8a2d7c1e4f6a8b0c2d4e6f8a1b3c")

# Send the request with headers:
# X-Merchant-Id, X-Timestamp, X-Nonce, X-Sign

Verify signature (callback)

rawBody is the exact JSON string received in the callback.

python
import hmac
import hashlib
import base64

def sign(timestamp: str, nonce: str, body: str, secret: str) -> str:
    sign_data = f"{timestamp}|{nonce}|{body}"
    digest = hmac.new(secret.encode("utf-8"),
                      sign_data.encode("utf-8"),
                      hashlib.sha256).digest()
    return base64.b64encode(digest).decode("utf-8")

def verify(timestamp: str, nonce: str, raw_body: str, secret: str, sign_header: str) -> bool:
    expected = sign(timestamp, nonce, raw_body, secret)
    return hmac.compare_digest(expected, sign_header)

raw_body = '{"payNo":"P202312230001","tradeStatus":"SUCCESS"}'
timestamp = "1734921005000"
nonce = "b2b2f3b6a6f24a4ba3dcd0e777c9a888"
sign_header = "base64_signature_from_header"

ok = verify(timestamp, nonce, raw_body, "sk_test_9f3b8a2d7c1e4f6a8b0c2d4e6f8a1b3c", sign_header)
print(ok)