{
  "schemaVersion": "1.0",
  "item": {
    "slug": "hongkong-payment-qfpay",
    "name": "HONGKONG-PAYMENT-QFPAY",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/xingstudy/hongkong-payment-qfpay",
    "canonicalUrl": "https://clawhub.ai/xingstudy/hongkong-payment-qfpay",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/hongkong-payment-qfpay",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=hongkong-payment-qfpay",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "README.md",
      "SKILL.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/hongkong-payment-qfpay"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/hongkong-payment-qfpay",
    "agentPageUrl": "https://openagent3.xyz/skills/hongkong-payment-qfpay/agent",
    "manifestUrl": "https://openagent3.xyz/skills/hongkong-payment-qfpay/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/hongkong-payment-qfpay/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Overview",
        "body": "QFPay API is a comprehensive payment solution that offers various payment methods to meet the needs of different businesses. This skill provides complete API integration guidelines including environment configuration, request formats, signature generation, payment types, supported currencies, and status codes."
      },
      {
        "title": "Environment Configuration",
        "body": "QFPay API is accessible via three main environments:\n\nEnvironmentBase URLDescriptionSandboxhttps://openapi-int.qfapi.comFor simulating payments without real fund deductionTestinghttps://test-openapi-hk.qfapi.comReal payment flow but linked to test accounts (no settlement)Productionhttps://openapi-hk.qfapi.comReal live payments with actual settlement\n\nImportant Notes:\n\nTransactions in Testing environment using test accounts will NOT be settled\nAlways ensure refunds are triggered immediately for test transactions\nMixing credentials or endpoints across environments will result in signature or authorization errors"
      },
      {
        "title": "Environment Variables Setup",
        "body": "Configure these environment variables before using the API:\n\nexport QFPAY_APPCODE=\"your_app_code_here\"\nexport QFPAY_KEY=\"your_client_key_here\"\nexport QFPAY_MCHID=\"your_merchant_id\"  # Optional, depends on account setup\nexport QFPAY_ENV=\"sandbox\"  # Options: prod, test, sandbox"
      },
      {
        "title": "Rate Limiting",
        "body": "To ensure fair usage and optimal performance:\n\nLimit: Maximum 100 requests per second (RPS) and 400 requests per minute per merchant\nExceeding Limit: API responds with HTTP 429 (Too Many Requests)"
      },
      {
        "title": "Best Practices",
        "body": "Batch Requests: Use batch processing to minimize individual requests\nEfficient Queries: Utilize filtering and pagination\nCaching: Implement response caching to avoid repeated requests\nMonitoring: Track API usage and implement logging for request patterns"
      },
      {
        "title": "Error Handling",
        "body": "When receiving HTTP 429:\n\nPause further requests for a specified duration\nImplement exponential backoff for retries\nLog errors for monitoring"
      },
      {
        "title": "Traffic Spike Management",
        "body": "For anticipated traffic spikes (e.g., promotional events), contact:\n\nTechnical Support: technical.support@qfpay.com"
      },
      {
        "title": "HTTP Request",
        "body": "POST /trade/v1/payment"
      },
      {
        "title": "Public Payment Request Parameters",
        "body": "AttributeRequiredTypeDescriptiontxamtYesInt(11)Transaction amount in cents (100 = $1). Suggest > 200 to avoid risk controltxcurrcdYesString(3)Transaction currency. See Currencies section for full listpay_typeYesString(6)Payment type code. See Payment Types sectionout_trade_noYesString(128)External transaction number. Must be unique per merchant accounttxdtmYesString(20)Transaction time format: YYYY-MM-DD hh:mm:ssauth_codeYes (CPM only)String(128)Authorization code for scanning barcode/QR. Expires within one dayexpired_timeNo (MPM only)String(3)QR expiration in minutes. Default: 30, Min: 5, Max: 120goods_nameNoString(64)Item description. Max 20 chars, UTF-8 for Chinese. Required for App paymentsmchidNoString(16)Merchant ID. Required if assigned, must NOT be included if not assignedudidNoString(40)Unique device ID for internal trackingnotify_urlNoString(256)URL for asynchronous payment notifications"
      },
      {
        "title": "HTTP Header Requirements",
        "body": "FieldRequiredDescriptionX-QF-APPCODEYesApp code assigned to merchantX-QF-SIGNYesSignature generated per signature algorithmX-QF-SIGNTYPENoSignature algorithm. Use SHA256 or defaults to MD5"
      },
      {
        "title": "Content Specifications",
        "body": "Character Encoding: UTF-8\nMethod: POST/GET (depends on endpoint)\nContent-Type: application/x-www-form-urlencoded"
      },
      {
        "title": "Success Response Structure",
        "body": "{\n  \"respcd\": \"0000\",\n  \"respmsg\": \"success\",\n  \"data\": {\n    \"txamt\": \"100\",\n    \"out_trade_no\": \"20231101000001\",\n    \"txcurrcd\": \"HKD\",\n    \"txstatus\": \"SUCCESS\",\n    \"qf_trade_no\": \"9000020231101000001\",\n    \"pay_type\": \"800101\",\n    \"txdtm\": \"2023-11-01 10:00:00\"\n  }\n}"
      },
      {
        "title": "Response Fields",
        "body": "FieldTypeDescriptionrespcdString(4)Return code. \"0000\" means successrespmsgString(64)Message description of respcddataObjectPayment transaction data"
      },
      {
        "title": "Data Object Fields",
        "body": "FieldTypeDescriptiontxamtStringTransaction amount in centsout_trade_noStringMerchant's original order numbertxcurrcdStringCurrency code (e.g., HKD)txstatusStringPayment status: SUCCESS, FAILED, PENDINGqf_trade_noStringQFPay's unique transaction numberpay_typeStringPayment method codetxdtmStringPayment time (YYYY-MM-DD HH:mm:ss)"
      },
      {
        "title": "Signature Verification",
        "body": "Response may include X-QF-SIGN and X-QF-SIGNTYPE headers. Verify by:\n\nExtracting data fields in sorted order\nConcatenating as key1=value1&key2=value2&...\nAppending client key\nGenerating MD5 hash and comparing"
      },
      {
        "title": "Signature Generation",
        "body": "All API requests must include a digital signature in the HTTP header:\n\nX-QF-SIGN: <your_signature>"
      },
      {
        "title": "Step-by-Step Guide",
        "body": "Step 1: Sort Parameters\n\nSort all request parameters by parameter name in ASCII ascending order.\n\nExample:\n\nParameterValuemchidZaMVg12345txamt100txcurrcdHKD\n\nSorted result:\n\nmchid=ZaMVg12345&txamt=100&txcurrcd=HKD\n\nStep 2: Append Client Key\n\nAppend your secret client_key to the string.\n\nIf client_key = abcd1234:\n\nmchid=ZaMVg12345&txamt=100&txcurrcd=HKDabcd1234\n\nStep 3: Hash the String\n\nHash using MD5 or SHA256 (SHA256 recommended):\n\nSHA256(\"mchid=ZaMVg12345&txamt=100&txcurrcd=HKDabcd1234\")\n\nStep 4: Add to Header\n\nX-QF-SIGN: <your_hashed_signature>"
      },
      {
        "title": "Important Notes",
        "body": "Do NOT insert line breaks, tabs, or extra spaces\nParameter names and values are case-sensitive\nDouble-check parameter order and encoding if signature fails"
      },
      {
        "title": "Code Examples",
        "body": "Python\n\nimport os\nimport hashlib\n\nAPPCODE = os.getenv('QFPAY_APPCODE')\nKEY = os.getenv('QFPAY_KEY')\n\ndef generate_signature(params, key):\n    \"\"\"Generate MD5 signature\"\"\"\n    keys = list(params.keys())\n    keys.sort()\n    query = []\n    for k in keys:\n        if k not in ('sign', 'sign_type') and (params[k] or params[k] == 0):\n            query.append(f'{k}={params[k]}')\n    \n    data = '&'.join(query) + key\n    md5 = hashlib.md5()\n    md5.update(data.encode('utf-8'))\n    return md5.hexdigest().upper()\n\ndef generate_signature_sha256(params, key):\n    \"\"\"Generate SHA256 signature\"\"\"\n    keys = list(params.keys())\n    keys.sort()\n    query = []\n    for k in keys:\n        if k not in ('sign', 'sign_type') and (params[k] or params[k] == 0):\n            query.append(f'{k}={params[k]}')\n    \n    data = '&'.join(query) + key\n    sha256 = hashlib.sha256()\n    sha256.update(data.encode('utf-8'))\n    return sha256.hexdigest().upper()"
      },
      {
        "title": "Payment Types",
        "body": "The pay_type parameter specifies which payment method to use. This affects transaction routing and UI requirements.\n\nNote: Not all pay_type values are enabled for every merchant. Contact technical.support@qfpay.com for clarification."
      },
      {
        "title": "Supported Payment Types",
        "body": "CodeDescription800008CPM for WeChat, Alipay, UnionPay QuickPass, PayMe800101Alipay MPM (Overseas Merchants)800108Alipay CPM (Overseas & HK Merchants)801101Alipay Web Payment (Overseas)801107Alipay WAP Payment (Overseas)801110Alipay In-App Payment (Overseas)800107Alipay Service Window H5 Payment801501Alipay MPM (HK Merchants)801510Alipay In-App (HK Merchants)801512Alipay WAP (HK Merchants)801514Alipay Web (HK Merchants)800201WeChat MPM (Overseas & HK)800208WeChat CPM (Overseas & HK)800207WeChat JSAPI Payment (Overseas & HK)800212WeChat H5 Payment800210WeChat In-App Payment (Overseas & HK)800213WeChat Mini-Program Payment801008WeChat Pay HK CPM (Direct Settlement, HK)801010WeChat Pay HK In-App (Direct Settlement, HK)805801PayMe MPM (HK Merchants)805808PayMe CPM (HK Merchants)805814PayMe Web Payment (HK Merchants)805812PayMe WAP Payment (HK Merchants)800701UnionPay QuickPass MPM800708UnionPay QuickPass CPM800712UnionPay WAP Payment (HK)800714UnionPay PC-Web Payment (HK)802001FPS MPM (HK Merchants)803701Octopus MPM (HK Merchants)803712Octopus WAP Payment (HK)803714Octopus PC-Web Payment (HK)802801Visa / Mastercard Online802808Visa / Mastercard Offline806527ApplePay Online806708UnionPay Card Offline806808American Express Card Offline"
      },
      {
        "title": "Special Remarks",
        "body": "801101: Transaction amount must be greater than 1 HKD\n802001: This payment method does not support refunds"
      },
      {
        "title": "Supported Currencies",
        "body": "All codes follow ISO 4217 format (3-letter uppercase):\n\nCodeDescriptionAEDArab Emirates DirhamCNYChinese YuanEUREuroHKDHong Kong DollarIDRIndonesian RupiahJPYJapanese YenMMKMyanmar KyatMYRMalaysian RinggitSGDSingapore DollarTHBThai BahtUSDUnited States DollarCADCanadian DollarAUDAustralian Dollar\n\nNote: Some payment methods may only support HKD. Verify with your integration manager before non-HKD transactions."
      },
      {
        "title": "Status Codes",
        "body": "Standard respcd values returned by QFPay API:\n\nCodeDescription0000Transaction successful1100System under maintenance1101Reversal error1102Duplicate request1103Request format error1104Request parameter error1105Device not activated1106Invalid device1107Device not allowed1108Signature error1125Transaction already refunded1136Transaction does not exist or not operational1142Order already closed1143Order not paid, password being entered1145Processing, please wait1147WeChat Pay transaction error1150T0 billing method does not support cancellation1155Refund request denied1181Order expired1201Insufficient balance1202Incorrect or expired payment code1203Merchant account error1204Bank error1205Transaction failed, try again later1212Please use UnionPay overseas payment code1241Store does not exist or status incorrect1242Store not configured correctly1243Store has been disabled1250Transaction forbidden1251Store configuration error1252System error making order request1254Problem occurred, resolving issue1260Order already paid1261Order not paid1262Order already refunded1263Order already cancelled1264Order already closed1265Transaction cannot be refunded (11:30pm-0:30am)1266Transaction amount wrong1267Order information mismatch1268Order does not exist1269Insufficient unsettled balance for refund1270Currency does not support partial refund1271Transaction does not support partial refund1272Refund amount exceeds maximum refundable1294Transaction non-compliant, prohibited by bank1295Connection slow, waiting for network response1296Connection slow, try again later1297Banking system busy1298Connection slow, do not repeat payment if already paid2005Customer payment code incorrect or expired2011Transaction serial number repeats"
      },
      {
        "title": "Complete Payment Flow (Python)",
        "body": "import os\nimport requests\nimport hashlib\nimport datetime\nimport time\n\n# Load configuration from environment variables\nAPPCODE = os.getenv('QFPAY_APPCODE')\nKEY = os.getenv('QFPAY_KEY')\nMCHID = os.getenv('QFPAY_MCHID')\nENV = os.getenv('QFPAY_ENV', 'test')\n\n# Environment URLs\nENV_URLS = {\n    'prod': 'https://openapi-hk.qfapi.com',\n    'test': 'https://test-openapi-hk.qfapi.com',\n    'sandbox': 'https://openapi-int.qfapi.com'\n}\n\nBASE_URL = ENV_URLS.get(ENV, ENV_URLS['test'])\n\ndef generate_signature(params, key, sign_type='SHA256'):\n    \"\"\"Generate signature for QFPay API request\"\"\"\n    keys = list(params.keys())\n    keys.sort()\n    query = []\n    for k in keys:\n        if k not in ('sign', 'sign_type') and (params[k] or params[k] == 0):\n            query.append(f'{k}={params[k]}')\n    \n    data = '&'.join(query) + key\n    \n    if sign_type == 'SHA256':\n        sha256 = hashlib.sha256()\n        sha256.update(data.encode('utf-8'))\n        return sha256.hexdigest().upper()\n    else:\n        md5 = hashlib.md5()\n        md5.update(data.encode('utf-8'))\n        return md5.hexdigest().upper()\n\ndef create_payment(amount, currency, pay_type, goods_name, notify_url=None):\n    \"\"\"Create a payment request\"\"\"\n    params = {\n        'txamt': str(amount),\n        'txcurrcd': currency,\n        'pay_type': pay_type,\n        'out_trade_no': f\"ORDER{int(time.time() * 10000)}\",\n        'txdtm': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),\n        'goods_name': goods_name\n    }\n    \n    if MCHID:\n        params['mchid'] = MCHID\n    \n    if notify_url:\n        params['notify_url'] = notify_url\n    \n    signature = generate_signature(params, KEY)\n    \n    headers = {\n        'X-QF-APPCODE': APPCODE,\n        'X-QF-SIGN': signature,\n        'Content-Type': 'application/x-www-form-urlencoded'\n    }\n    \n    response = requests.post(\n        f'{BASE_URL}/trade/v1/payment',\n        data=params,\n        headers=headers\n    )\n    \n    return response.json()\n\ndef query_transaction(out_trade_no):\n    \"\"\"Query transaction status\"\"\"\n    params = {\n        'out_trade_no': out_trade_no,\n        'txdtm': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')\n    }\n    \n    if MCHID:\n        params['mchid'] = MCHID\n    \n    signature = generate_signature(params, KEY)\n    \n    headers = {\n        'X-QF-APPCODE': APPCODE,\n        'X-QF-SIGN': signature,\n        'Content-Type': 'application/x-www-form-urlencoded'\n    }\n    \n    response = requests.post(\n        f'{BASE_URL}/trade/v1/query',\n        data=params,\n        headers=headers\n    )\n    \n    return response.json()\n\ndef refund_transaction(out_trade_no, txamt, qf_trade_no=None):\n    \"\"\"Process a refund\"\"\"\n    params = {\n        'out_trade_no': out_trade_no,\n        'txamt': str(txamt),\n        'txdtm': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')\n    }\n    \n    if qf_trade_no:\n        params['qf_trade_no'] = qf_trade_no\n    \n    if MCHID:\n        params['mchid'] = MCHID\n    \n    signature = generate_signature(params, KEY)\n    \n    headers = {\n        'X-QF-APPCODE': APPCODE,\n        'X-QF-SIGN': signature,\n        'Content-Type': 'application/x-www-form-urlencoded'\n    }\n    \n    response = requests.post(\n        f'{BASE_URL}/trade/v1/refund',\n        data=params,\n        headers=headers\n    )\n    \n    return response.json()\n\n# Example usage\nif __name__ == '__main__':\n    # Create a payment\n    result = create_payment(\n        amount=100,  # $1.00 HKD\n        currency='HKD',\n        pay_type='800101',\n        goods_name='Test Product'\n    )\n    print(f\"Payment created: {result}\")\n    \n    if result.get('respcd') == '0000':\n        out_trade_no = result['data']['out_trade_no']\n        \n        # Query transaction\n        query_result = query_transaction(out_trade_no)\n        print(f\"Transaction status: {query_result}\")"
      },
      {
        "title": "Environment Configuration with Multiple Merchants",
        "body": "import os\n\n# Configuration loader from environment\nclass QFPayConfig:\n    def __init__(self, env='sandbox'):\n        self.env = env\n        self.appcode = os.getenv(f'QFPAY_{env.upper()}_APPCODE') or os.getenv('QFPAY_APPCODE')\n        self.key = os.getenv(f'QFPAY_{env.upper()}_KEY') or os.getenv('QFPAY_KEY')\n        self.mchid = os.getenv(f'QFPAY_{env.upper()}_MCHID') or os.getenv('QFPAY_MCHID')\n        \n    @property\n    def base_url(self):\n        urls = {\n            'prod': 'https://openapi-hk.qfapi.com',\n            'test': 'https://test-openapi-hk.qfapi.com',\n            'sandbox': 'https://openapi-int.qfapi.com'\n        }\n        return urls.get(self.env, urls['sandbox'])\n\n# Usage\nconfig = QFPayConfig(env=os.getenv('QFPAY_ENV', 'sandbox'))\nprint(f\"Using base URL: {config.base_url}\")"
      },
      {
        "title": "Important Notes",
        "body": "Signature Security: Never expose your client_key in frontend code or client-side applications. Always compute signatures on the server side.\n\n\nOrder Number Uniqueness: out_trade_no must be unique across all payment and refund requests under the same merchant account.\n\n\nCharacter Encoding: All requests and responses use UTF-8 encoding.\n\n\nTimeout Handling: For payment requests that don't return promptly, implement a polling mechanism to query transaction status.\n\n\nAsync Notifications: Configure notify_url to receive asynchronous payment completion notifications and verify notification signatures.\n\n\nRefund Limitations: FPS (802001) payment type does not support refunds. Confirm business requirements before integration.\n\n\nAmount Format: Amount is in cents. For example, 100 represents 1 HKD.\n\n\nTimezone: The txdtm parameter uses the merchant's local timezone.\n\n\nEnvironment Variables: Always load sensitive credentials from environment variables, never hardcode them in source files."
      },
      {
        "title": "Technical Support",
        "body": "For any integration issues, contact:\n\nEmail: technical.support@qfpay.com\nDocumentation: https://sdk.qfapi.com\nPostman Collection: https://sdk.qfapi.com/assets/files/qfpay_openapi_payment_request.postman_collection-c8de8c8fe69f3fcd5a7653d41c289a29.json"
      },
      {
        "title": "See Also",
        "body": "QFPay Developer Center\nPayment Integration Guides\nCheckout Integration"
      }
    ],
    "body": "QFPay Payment API Skill\nOverview\n\nQFPay API is a comprehensive payment solution that offers various payment methods to meet the needs of different businesses. This skill provides complete API integration guidelines including environment configuration, request formats, signature generation, payment types, supported currencies, and status codes.\n\nEnvironment Configuration\n\nQFPay API is accessible via three main environments:\n\nEnvironment\tBase URL\tDescription\nSandbox\thttps://openapi-int.qfapi.com\tFor simulating payments without real fund deduction\nTesting\thttps://test-openapi-hk.qfapi.com\tReal payment flow but linked to test accounts (no settlement)\nProduction\thttps://openapi-hk.qfapi.com\tReal live payments with actual settlement\n\nImportant Notes:\n\nTransactions in Testing environment using test accounts will NOT be settled\nAlways ensure refunds are triggered immediately for test transactions\nMixing credentials or endpoints across environments will result in signature or authorization errors\nEnvironment Variables Setup\n\nConfigure these environment variables before using the API:\n\nexport QFPAY_APPCODE=\"your_app_code_here\"\nexport QFPAY_KEY=\"your_client_key_here\"\nexport QFPAY_MCHID=\"your_merchant_id\"  # Optional, depends on account setup\nexport QFPAY_ENV=\"sandbox\"  # Options: prod, test, sandbox\n\nAPI Usage Guidelines\nRate Limiting\n\nTo ensure fair usage and optimal performance:\n\nLimit: Maximum 100 requests per second (RPS) and 400 requests per minute per merchant\nExceeding Limit: API responds with HTTP 429 (Too Many Requests)\nBest Practices\nBatch Requests: Use batch processing to minimize individual requests\nEfficient Queries: Utilize filtering and pagination\nCaching: Implement response caching to avoid repeated requests\nMonitoring: Track API usage and implement logging for request patterns\nError Handling\n\nWhen receiving HTTP 429:\n\nPause further requests for a specified duration\nImplement exponential backoff for retries\nLog errors for monitoring\nTraffic Spike Management\n\nFor anticipated traffic spikes (e.g., promotional events), contact:\n\nTechnical Support: technical.support@qfpay.com\nRequest Format\nHTTP Request\nPOST /trade/v1/payment\n\nPublic Payment Request Parameters\nAttribute\tRequired\tType\tDescription\ntxamt\tYes\tInt(11)\tTransaction amount in cents (100 = $1). Suggest > 200 to avoid risk control\ntxcurrcd\tYes\tString(3)\tTransaction currency. See Currencies section for full list\npay_type\tYes\tString(6)\tPayment type code. See Payment Types section\nout_trade_no\tYes\tString(128)\tExternal transaction number. Must be unique per merchant account\ntxdtm\tYes\tString(20)\tTransaction time format: YYYY-MM-DD hh:mm:ss\nauth_code\tYes (CPM only)\tString(128)\tAuthorization code for scanning barcode/QR. Expires within one day\nexpired_time\tNo (MPM only)\tString(3)\tQR expiration in minutes. Default: 30, Min: 5, Max: 120\ngoods_name\tNo\tString(64)\tItem description. Max 20 chars, UTF-8 for Chinese. Required for App payments\nmchid\tNo\tString(16)\tMerchant ID. Required if assigned, must NOT be included if not assigned\nudid\tNo\tString(40)\tUnique device ID for internal tracking\nnotify_url\tNo\tString(256)\tURL for asynchronous payment notifications\nHTTP Header Requirements\nField\tRequired\tDescription\nX-QF-APPCODE\tYes\tApp code assigned to merchant\nX-QF-SIGN\tYes\tSignature generated per signature algorithm\nX-QF-SIGNTYPE\tNo\tSignature algorithm. Use SHA256 or defaults to MD5\nContent Specifications\nCharacter Encoding: UTF-8\nMethod: POST/GET (depends on endpoint)\nContent-Type: application/x-www-form-urlencoded\nResponse Format\nSuccess Response Structure\n{\n  \"respcd\": \"0000\",\n  \"respmsg\": \"success\",\n  \"data\": {\n    \"txamt\": \"100\",\n    \"out_trade_no\": \"20231101000001\",\n    \"txcurrcd\": \"HKD\",\n    \"txstatus\": \"SUCCESS\",\n    \"qf_trade_no\": \"9000020231101000001\",\n    \"pay_type\": \"800101\",\n    \"txdtm\": \"2023-11-01 10:00:00\"\n  }\n}\n\nResponse Fields\nField\tType\tDescription\nrespcd\tString(4)\tReturn code. \"0000\" means success\nrespmsg\tString(64)\tMessage description of respcd\ndata\tObject\tPayment transaction data\nData Object Fields\nField\tType\tDescription\ntxamt\tString\tTransaction amount in cents\nout_trade_no\tString\tMerchant's original order number\ntxcurrcd\tString\tCurrency code (e.g., HKD)\ntxstatus\tString\tPayment status: SUCCESS, FAILED, PENDING\nqf_trade_no\tString\tQFPay's unique transaction number\npay_type\tString\tPayment method code\ntxdtm\tString\tPayment time (YYYY-MM-DD HH:mm:ss)\nSignature Verification\n\nResponse may include X-QF-SIGN and X-QF-SIGNTYPE headers. Verify by:\n\nExtracting data fields in sorted order\nConcatenating as key1=value1&key2=value2&...\nAppending client key\nGenerating MD5 hash and comparing\nSignature Generation\n\nAll API requests must include a digital signature in the HTTP header:\n\nX-QF-SIGN: <your_signature>\n\nStep-by-Step Guide\nStep 1: Sort Parameters\n\nSort all request parameters by parameter name in ASCII ascending order.\n\nExample:\n\nParameter\tValue\nmchid\tZaMVg12345\ntxamt\t100\ntxcurrcd\tHKD\n\nSorted result:\n\nmchid=ZaMVg12345&txamt=100&txcurrcd=HKD\n\nStep 2: Append Client Key\n\nAppend your secret client_key to the string.\n\nIf client_key = abcd1234:\n\nmchid=ZaMVg12345&txamt=100&txcurrcd=HKDabcd1234\n\nStep 3: Hash the String\n\nHash using MD5 or SHA256 (SHA256 recommended):\n\nSHA256(\"mchid=ZaMVg12345&txamt=100&txcurrcd=HKDabcd1234\")\n\nStep 4: Add to Header\nX-QF-SIGN: <your_hashed_signature>\n\nImportant Notes\nDo NOT insert line breaks, tabs, or extra spaces\nParameter names and values are case-sensitive\nDouble-check parameter order and encoding if signature fails\nCode Examples\nPython\nimport os\nimport hashlib\n\nAPPCODE = os.getenv('QFPAY_APPCODE')\nKEY = os.getenv('QFPAY_KEY')\n\ndef generate_signature(params, key):\n    \"\"\"Generate MD5 signature\"\"\"\n    keys = list(params.keys())\n    keys.sort()\n    query = []\n    for k in keys:\n        if k not in ('sign', 'sign_type') and (params[k] or params[k] == 0):\n            query.append(f'{k}={params[k]}')\n    \n    data = '&'.join(query) + key\n    md5 = hashlib.md5()\n    md5.update(data.encode('utf-8'))\n    return md5.hexdigest().upper()\n\ndef generate_signature_sha256(params, key):\n    \"\"\"Generate SHA256 signature\"\"\"\n    keys = list(params.keys())\n    keys.sort()\n    query = []\n    for k in keys:\n        if k not in ('sign', 'sign_type') and (params[k] or params[k] == 0):\n            query.append(f'{k}={params[k]}')\n    \n    data = '&'.join(query) + key\n    sha256 = hashlib.sha256()\n    sha256.update(data.encode('utf-8'))\n    return sha256.hexdigest().upper()\n\nPayment Types\n\nThe pay_type parameter specifies which payment method to use. This affects transaction routing and UI requirements.\n\nNote: Not all pay_type values are enabled for every merchant. Contact technical.support@qfpay.com for clarification.\n\nSupported Payment Types\nCode\tDescription\n800008\tCPM for WeChat, Alipay, UnionPay QuickPass, PayMe\n800101\tAlipay MPM (Overseas Merchants)\n800108\tAlipay CPM (Overseas & HK Merchants)\n801101\tAlipay Web Payment (Overseas)\n801107\tAlipay WAP Payment (Overseas)\n801110\tAlipay In-App Payment (Overseas)\n800107\tAlipay Service Window H5 Payment\n801501\tAlipay MPM (HK Merchants)\n801510\tAlipay In-App (HK Merchants)\n801512\tAlipay WAP (HK Merchants)\n801514\tAlipay Web (HK Merchants)\n800201\tWeChat MPM (Overseas & HK)\n800208\tWeChat CPM (Overseas & HK)\n800207\tWeChat JSAPI Payment (Overseas & HK)\n800212\tWeChat H5 Payment\n800210\tWeChat In-App Payment (Overseas & HK)\n800213\tWeChat Mini-Program Payment\n801008\tWeChat Pay HK CPM (Direct Settlement, HK)\n801010\tWeChat Pay HK In-App (Direct Settlement, HK)\n805801\tPayMe MPM (HK Merchants)\n805808\tPayMe CPM (HK Merchants)\n805814\tPayMe Web Payment (HK Merchants)\n805812\tPayMe WAP Payment (HK Merchants)\n800701\tUnionPay QuickPass MPM\n800708\tUnionPay QuickPass CPM\n800712\tUnionPay WAP Payment (HK)\n800714\tUnionPay PC-Web Payment (HK)\n802001\tFPS MPM (HK Merchants)\n803701\tOctopus MPM (HK Merchants)\n803712\tOctopus WAP Payment (HK)\n803714\tOctopus PC-Web Payment (HK)\n802801\tVisa / Mastercard Online\n802808\tVisa / Mastercard Offline\n806527\tApplePay Online\n806708\tUnionPay Card Offline\n806808\tAmerican Express Card Offline\nSpecial Remarks\n801101: Transaction amount must be greater than 1 HKD\n802001: This payment method does not support refunds\nSupported Currencies\n\nAll codes follow ISO 4217 format (3-letter uppercase):\n\nCode\tDescription\nAED\tArab Emirates Dirham\nCNY\tChinese Yuan\nEUR\tEuro\nHKD\tHong Kong Dollar\nIDR\tIndonesian Rupiah\nJPY\tJapanese Yen\nMMK\tMyanmar Kyat\nMYR\tMalaysian Ringgit\nSGD\tSingapore Dollar\nTHB\tThai Baht\nUSD\tUnited States Dollar\nCAD\tCanadian Dollar\nAUD\tAustralian Dollar\n\nNote: Some payment methods may only support HKD. Verify with your integration manager before non-HKD transactions.\n\nStatus Codes\n\nStandard respcd values returned by QFPay API:\n\nCode\tDescription\n0000\tTransaction successful\n1100\tSystem under maintenance\n1101\tReversal error\n1102\tDuplicate request\n1103\tRequest format error\n1104\tRequest parameter error\n1105\tDevice not activated\n1106\tInvalid device\n1107\tDevice not allowed\n1108\tSignature error\n1125\tTransaction already refunded\n1136\tTransaction does not exist or not operational\n1142\tOrder already closed\n1143\tOrder not paid, password being entered\n1145\tProcessing, please wait\n1147\tWeChat Pay transaction error\n1150\tT0 billing method does not support cancellation\n1155\tRefund request denied\n1181\tOrder expired\n1201\tInsufficient balance\n1202\tIncorrect or expired payment code\n1203\tMerchant account error\n1204\tBank error\n1205\tTransaction failed, try again later\n1212\tPlease use UnionPay overseas payment code\n1241\tStore does not exist or status incorrect\n1242\tStore not configured correctly\n1243\tStore has been disabled\n1250\tTransaction forbidden\n1251\tStore configuration error\n1252\tSystem error making order request\n1254\tProblem occurred, resolving issue\n1260\tOrder already paid\n1261\tOrder not paid\n1262\tOrder already refunded\n1263\tOrder already cancelled\n1264\tOrder already closed\n1265\tTransaction cannot be refunded (11:30pm-0:30am)\n1266\tTransaction amount wrong\n1267\tOrder information mismatch\n1268\tOrder does not exist\n1269\tInsufficient unsettled balance for refund\n1270\tCurrency does not support partial refund\n1271\tTransaction does not support partial refund\n1272\tRefund amount exceeds maximum refundable\n1294\tTransaction non-compliant, prohibited by bank\n1295\tConnection slow, waiting for network response\n1296\tConnection slow, try again later\n1297\tBanking system busy\n1298\tConnection slow, do not repeat payment if already paid\n2005\tCustomer payment code incorrect or expired\n2011\tTransaction serial number repeats\nUsage Examples\nComplete Payment Flow (Python)\nimport os\nimport requests\nimport hashlib\nimport datetime\nimport time\n\n# Load configuration from environment variables\nAPPCODE = os.getenv('QFPAY_APPCODE')\nKEY = os.getenv('QFPAY_KEY')\nMCHID = os.getenv('QFPAY_MCHID')\nENV = os.getenv('QFPAY_ENV', 'test')\n\n# Environment URLs\nENV_URLS = {\n    'prod': 'https://openapi-hk.qfapi.com',\n    'test': 'https://test-openapi-hk.qfapi.com',\n    'sandbox': 'https://openapi-int.qfapi.com'\n}\n\nBASE_URL = ENV_URLS.get(ENV, ENV_URLS['test'])\n\ndef generate_signature(params, key, sign_type='SHA256'):\n    \"\"\"Generate signature for QFPay API request\"\"\"\n    keys = list(params.keys())\n    keys.sort()\n    query = []\n    for k in keys:\n        if k not in ('sign', 'sign_type') and (params[k] or params[k] == 0):\n            query.append(f'{k}={params[k]}')\n    \n    data = '&'.join(query) + key\n    \n    if sign_type == 'SHA256':\n        sha256 = hashlib.sha256()\n        sha256.update(data.encode('utf-8'))\n        return sha256.hexdigest().upper()\n    else:\n        md5 = hashlib.md5()\n        md5.update(data.encode('utf-8'))\n        return md5.hexdigest().upper()\n\ndef create_payment(amount, currency, pay_type, goods_name, notify_url=None):\n    \"\"\"Create a payment request\"\"\"\n    params = {\n        'txamt': str(amount),\n        'txcurrcd': currency,\n        'pay_type': pay_type,\n        'out_trade_no': f\"ORDER{int(time.time() * 10000)}\",\n        'txdtm': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),\n        'goods_name': goods_name\n    }\n    \n    if MCHID:\n        params['mchid'] = MCHID\n    \n    if notify_url:\n        params['notify_url'] = notify_url\n    \n    signature = generate_signature(params, KEY)\n    \n    headers = {\n        'X-QF-APPCODE': APPCODE,\n        'X-QF-SIGN': signature,\n        'Content-Type': 'application/x-www-form-urlencoded'\n    }\n    \n    response = requests.post(\n        f'{BASE_URL}/trade/v1/payment',\n        data=params,\n        headers=headers\n    )\n    \n    return response.json()\n\ndef query_transaction(out_trade_no):\n    \"\"\"Query transaction status\"\"\"\n    params = {\n        'out_trade_no': out_trade_no,\n        'txdtm': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')\n    }\n    \n    if MCHID:\n        params['mchid'] = MCHID\n    \n    signature = generate_signature(params, KEY)\n    \n    headers = {\n        'X-QF-APPCODE': APPCODE,\n        'X-QF-SIGN': signature,\n        'Content-Type': 'application/x-www-form-urlencoded'\n    }\n    \n    response = requests.post(\n        f'{BASE_URL}/trade/v1/query',\n        data=params,\n        headers=headers\n    )\n    \n    return response.json()\n\ndef refund_transaction(out_trade_no, txamt, qf_trade_no=None):\n    \"\"\"Process a refund\"\"\"\n    params = {\n        'out_trade_no': out_trade_no,\n        'txamt': str(txamt),\n        'txdtm': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')\n    }\n    \n    if qf_trade_no:\n        params['qf_trade_no'] = qf_trade_no\n    \n    if MCHID:\n        params['mchid'] = MCHID\n    \n    signature = generate_signature(params, KEY)\n    \n    headers = {\n        'X-QF-APPCODE': APPCODE,\n        'X-QF-SIGN': signature,\n        'Content-Type': 'application/x-www-form-urlencoded'\n    }\n    \n    response = requests.post(\n        f'{BASE_URL}/trade/v1/refund',\n        data=params,\n        headers=headers\n    )\n    \n    return response.json()\n\n# Example usage\nif __name__ == '__main__':\n    # Create a payment\n    result = create_payment(\n        amount=100,  # $1.00 HKD\n        currency='HKD',\n        pay_type='800101',\n        goods_name='Test Product'\n    )\n    print(f\"Payment created: {result}\")\n    \n    if result.get('respcd') == '0000':\n        out_trade_no = result['data']['out_trade_no']\n        \n        # Query transaction\n        query_result = query_transaction(out_trade_no)\n        print(f\"Transaction status: {query_result}\")\n\nEnvironment Configuration with Multiple Merchants\nimport os\n\n# Configuration loader from environment\nclass QFPayConfig:\n    def __init__(self, env='sandbox'):\n        self.env = env\n        self.appcode = os.getenv(f'QFPAY_{env.upper()}_APPCODE') or os.getenv('QFPAY_APPCODE')\n        self.key = os.getenv(f'QFPAY_{env.upper()}_KEY') or os.getenv('QFPAY_KEY')\n        self.mchid = os.getenv(f'QFPAY_{env.upper()}_MCHID') or os.getenv('QFPAY_MCHID')\n        \n    @property\n    def base_url(self):\n        urls = {\n            'prod': 'https://openapi-hk.qfapi.com',\n            'test': 'https://test-openapi-hk.qfapi.com',\n            'sandbox': 'https://openapi-int.qfapi.com'\n        }\n        return urls.get(self.env, urls['sandbox'])\n\n# Usage\nconfig = QFPayConfig(env=os.getenv('QFPAY_ENV', 'sandbox'))\nprint(f\"Using base URL: {config.base_url}\")\n\nImportant Notes\n\nSignature Security: Never expose your client_key in frontend code or client-side applications. Always compute signatures on the server side.\n\nOrder Number Uniqueness: out_trade_no must be unique across all payment and refund requests under the same merchant account.\n\nCharacter Encoding: All requests and responses use UTF-8 encoding.\n\nTimeout Handling: For payment requests that don't return promptly, implement a polling mechanism to query transaction status.\n\nAsync Notifications: Configure notify_url to receive asynchronous payment completion notifications and verify notification signatures.\n\nRefund Limitations: FPS (802001) payment type does not support refunds. Confirm business requirements before integration.\n\nAmount Format: Amount is in cents. For example, 100 represents 1 HKD.\n\nTimezone: The txdtm parameter uses the merchant's local timezone.\n\nEnvironment Variables: Always load sensitive credentials from environment variables, never hardcode them in source files.\n\nTechnical Support\n\nFor any integration issues, contact:\n\nEmail: technical.support@qfpay.com\nDocumentation: https://sdk.qfapi.com\nPostman Collection: https://sdk.qfapi.com/assets/files/qfpay_openapi_payment_request.postman_collection-c8de8c8fe69f3fcd5a7653d41c289a29.json\nSee Also\nQFPay Developer Center\nPayment Integration Guides\nCheckout Integration"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/xingstudy/hongkong-payment-qfpay",
    "publisherUrl": "https://clawhub.ai/xingstudy/hongkong-payment-qfpay",
    "owner": "xingstudy",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/hongkong-payment-qfpay",
    "downloadUrl": "https://openagent3.xyz/downloads/hongkong-payment-qfpay",
    "agentUrl": "https://openagent3.xyz/skills/hongkong-payment-qfpay/agent",
    "manifestUrl": "https://openagent3.xyz/skills/hongkong-payment-qfpay/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/hongkong-payment-qfpay/agent.md"
  }
}