Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
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.
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.
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
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.
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.
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.
QFPay API is accessible via three main environments: EnvironmentBase 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 Important Notes: Transactions in Testing environment using test accounts will NOT be settled Always ensure refunds are triggered immediately for test transactions Mixing credentials or endpoints across environments will result in signature or authorization errors
Configure these environment variables before using the API: export QFPAY_APPCODE="your_app_code_here" export QFPAY_KEY="your_client_key_here" export QFPAY_MCHID="your_merchant_id" # Optional, depends on account setup export QFPAY_ENV="sandbox" # Options: prod, test, sandbox
To ensure fair usage and optimal performance: Limit: Maximum 100 requests per second (RPS) and 400 requests per minute per merchant Exceeding Limit: API responds with HTTP 429 (Too Many Requests)
Batch Requests: Use batch processing to minimize individual requests Efficient Queries: Utilize filtering and pagination Caching: Implement response caching to avoid repeated requests Monitoring: Track API usage and implement logging for request patterns
When receiving HTTP 429: Pause further requests for a specified duration Implement exponential backoff for retries Log errors for monitoring
For anticipated traffic spikes (e.g., promotional events), contact: Technical Support: technical.support@qfpay.com
POST /trade/v1/payment
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
FieldRequiredDescriptionX-QF-APPCODEYesApp code assigned to merchantX-QF-SIGNYesSignature generated per signature algorithmX-QF-SIGNTYPENoSignature algorithm. Use SHA256 or defaults to MD5
Character Encoding: UTF-8 Method: POST/GET (depends on endpoint) Content-Type: application/x-www-form-urlencoded
{ "respcd": "0000", "respmsg": "success", "data": { "txamt": "100", "out_trade_no": "20231101000001", "txcurrcd": "HKD", "txstatus": "SUCCESS", "qf_trade_no": "9000020231101000001", "pay_type": "800101", "txdtm": "2023-11-01 10:00:00" } }
FieldTypeDescriptionrespcdString(4)Return code. "0000" means successrespmsgString(64)Message description of respcddataObjectPayment transaction data
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)
Response may include X-QF-SIGN and X-QF-SIGNTYPE headers. Verify by: Extracting data fields in sorted order Concatenating as key1=value1&key2=value2&... Appending client key Generating MD5 hash and comparing
All API requests must include a digital signature in the HTTP header: X-QF-SIGN: <your_signature>
Step 1: Sort Parameters Sort all request parameters by parameter name in ASCII ascending order. Example: ParameterValuemchidZaMVg12345txamt100txcurrcdHKD Sorted result: mchid=ZaMVg12345&txamt=100&txcurrcd=HKD Step 2: Append Client Key Append your secret client_key to the string. If client_key = abcd1234: mchid=ZaMVg12345&txamt=100&txcurrcd=HKDabcd1234 Step 3: Hash the String Hash using MD5 or SHA256 (SHA256 recommended): SHA256("mchid=ZaMVg12345&txamt=100&txcurrcd=HKDabcd1234") Step 4: Add to Header X-QF-SIGN: <your_hashed_signature>
Do NOT insert line breaks, tabs, or extra spaces Parameter names and values are case-sensitive Double-check parameter order and encoding if signature fails
Python import os import hashlib APPCODE = os.getenv('QFPAY_APPCODE') KEY = os.getenv('QFPAY_KEY') def generate_signature(params, key): """Generate MD5 signature""" keys = list(params.keys()) keys.sort() query = [] for k in keys: if k not in ('sign', 'sign_type') and (params[k] or params[k] == 0): query.append(f'{k}={params[k]}') data = '&'.join(query) + key md5 = hashlib.md5() md5.update(data.encode('utf-8')) return md5.hexdigest().upper() def generate_signature_sha256(params, key): """Generate SHA256 signature""" keys = list(params.keys()) keys.sort() query = [] for k in keys: if k not in ('sign', 'sign_type') and (params[k] or params[k] == 0): query.append(f'{k}={params[k]}') data = '&'.join(query) + key sha256 = hashlib.sha256() sha256.update(data.encode('utf-8')) return sha256.hexdigest().upper()
The pay_type parameter specifies which payment method to use. This affects transaction routing and UI requirements. Note: Not all pay_type values are enabled for every merchant. Contact technical.support@qfpay.com for clarification.
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
801101: Transaction amount must be greater than 1 HKD 802001: This payment method does not support refunds
All codes follow ISO 4217 format (3-letter uppercase): CodeDescriptionAEDArab Emirates DirhamCNYChinese YuanEUREuroHKDHong Kong DollarIDRIndonesian RupiahJPYJapanese YenMMKMyanmar KyatMYRMalaysian RinggitSGDSingapore DollarTHBThai BahtUSDUnited States DollarCADCanadian DollarAUDAustralian Dollar Note: Some payment methods may only support HKD. Verify with your integration manager before non-HKD transactions.
Standard respcd values returned by QFPay API: CodeDescription0000Transaction 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
import os import requests import hashlib import datetime import time # Load configuration from environment variables APPCODE = os.getenv('QFPAY_APPCODE') KEY = os.getenv('QFPAY_KEY') MCHID = os.getenv('QFPAY_MCHID') ENV = os.getenv('QFPAY_ENV', 'test') # Environment URLs ENV_URLS = { 'prod': 'https://openapi-hk.qfapi.com', 'test': 'https://test-openapi-hk.qfapi.com', 'sandbox': 'https://openapi-int.qfapi.com' } BASE_URL = ENV_URLS.get(ENV, ENV_URLS['test']) def generate_signature(params, key, sign_type='SHA256'): """Generate signature for QFPay API request""" keys = list(params.keys()) keys.sort() query = [] for k in keys: if k not in ('sign', 'sign_type') and (params[k] or params[k] == 0): query.append(f'{k}={params[k]}') data = '&'.join(query) + key if sign_type == 'SHA256': sha256 = hashlib.sha256() sha256.update(data.encode('utf-8')) return sha256.hexdigest().upper() else: md5 = hashlib.md5() md5.update(data.encode('utf-8')) return md5.hexdigest().upper() def create_payment(amount, currency, pay_type, goods_name, notify_url=None): """Create a payment request""" params = { 'txamt': str(amount), 'txcurrcd': currency, 'pay_type': pay_type, 'out_trade_no': f"ORDER{int(time.time() * 10000)}", 'txdtm': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), 'goods_name': goods_name } if MCHID: params['mchid'] = MCHID if notify_url: params['notify_url'] = notify_url signature = generate_signature(params, KEY) headers = { 'X-QF-APPCODE': APPCODE, 'X-QF-SIGN': signature, 'Content-Type': 'application/x-www-form-urlencoded' } response = requests.post( f'{BASE_URL}/trade/v1/payment', data=params, headers=headers ) return response.json() def query_transaction(out_trade_no): """Query transaction status""" params = { 'out_trade_no': out_trade_no, 'txdtm': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') } if MCHID: params['mchid'] = MCHID signature = generate_signature(params, KEY) headers = { 'X-QF-APPCODE': APPCODE, 'X-QF-SIGN': signature, 'Content-Type': 'application/x-www-form-urlencoded' } response = requests.post( f'{BASE_URL}/trade/v1/query', data=params, headers=headers ) return response.json() def refund_transaction(out_trade_no, txamt, qf_trade_no=None): """Process a refund""" params = { 'out_trade_no': out_trade_no, 'txamt': str(txamt), 'txdtm': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') } if qf_trade_no: params['qf_trade_no'] = qf_trade_no if MCHID: params['mchid'] = MCHID signature = generate_signature(params, KEY) headers = { 'X-QF-APPCODE': APPCODE, 'X-QF-SIGN': signature, 'Content-Type': 'application/x-www-form-urlencoded' } response = requests.post( f'{BASE_URL}/trade/v1/refund', data=params, headers=headers ) return response.json() # Example usage if __name__ == '__main__': # Create a payment result = create_payment( amount=100, # $1.00 HKD currency='HKD', pay_type='800101', goods_name='Test Product' ) print(f"Payment created: {result}") if result.get('respcd') == '0000': out_trade_no = result['data']['out_trade_no'] # Query transaction query_result = query_transaction(out_trade_no) print(f"Transaction status: {query_result}")
import os # Configuration loader from environment class QFPayConfig: def __init__(self, env='sandbox'): self.env = env self.appcode = os.getenv(f'QFPAY_{env.upper()}_APPCODE') or os.getenv('QFPAY_APPCODE') self.key = os.getenv(f'QFPAY_{env.upper()}_KEY') or os.getenv('QFPAY_KEY') self.mchid = os.getenv(f'QFPAY_{env.upper()}_MCHID') or os.getenv('QFPAY_MCHID') @property def base_url(self): urls = { 'prod': 'https://openapi-hk.qfapi.com', 'test': 'https://test-openapi-hk.qfapi.com', 'sandbox': 'https://openapi-int.qfapi.com' } return urls.get(self.env, urls['sandbox']) # Usage config = QFPayConfig(env=os.getenv('QFPAY_ENV', 'sandbox')) print(f"Using base URL: {config.base_url}")
Signature Security: Never expose your client_key in frontend code or client-side applications. Always compute signatures on the server side. Order Number Uniqueness: out_trade_no must be unique across all payment and refund requests under the same merchant account. Character Encoding: All requests and responses use UTF-8 encoding. Timeout Handling: For payment requests that don't return promptly, implement a polling mechanism to query transaction status. Async Notifications: Configure notify_url to receive asynchronous payment completion notifications and verify notification signatures. Refund Limitations: FPS (802001) payment type does not support refunds. Confirm business requirements before integration. Amount Format: Amount is in cents. For example, 100 represents 1 HKD. Timezone: The txdtm parameter uses the merchant's local timezone. Environment Variables: Always load sensitive credentials from environment variables, never hardcode them in source files.
For any integration issues, contact: Email: technical.support@qfpay.com Documentation: https://sdk.qfapi.com Postman Collection: https://sdk.qfapi.com/assets/files/qfpay_openapi_payment_request.postman_collection-c8de8c8fe69f3fcd5a7653d41c289a29.json
QFPay Developer Center Payment Integration Guides Checkout Integration
Code helpers, APIs, CLIs, browser automation, testing, and developer operations.
Largest current source with strong distribution and engagement signals.