### WeChat Mini Program Boilerplate Setup Instructions Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/online-shop/wechat/wechat-mini-programs Step-by-step guide for setting up the QFPay WeChat Mini Program Boilerplate, including signing up with QFPay, whitelisting server domains in WeChat MP portal, copying files, setting up cloud functions, and obtaining user openid. ```APIDOC Setup Instructions: 1. Sign up with QFPay and we bind your WeChat appid to your API credentials. 2. Visit the WeChat MP portal at https://mp.weixin.qq.com and whitelist our environment for incoming server traffic: 开发 -> 开发设置 -> 服务器域名 -> request合法域名: e.g. `https://test-openapi-hk.qfapi.com` 3. Copy and paste the files from the zip file to your local harddrive and setup a cloudfunction environment. 4. Obtain the user openid with the cloudfunction "getUserOpenID" and run the API calls accroding to the code. ``` -------------------------------- ### Example JSON Response for Pre-authorisation Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/online-shop/paymentelement An example JSON object showing the typical parameters returned in a successful pre-authorisation response, including transaction details, system timestamp, and payment intent information. ```JSON { "respcd": "0000", "txamt": "123", "txcurrcd": "123", "sysdtm": "2022-11-14 16:15:16", "out_trade_no": "501871840", "payment_intent": "38aec7cef8564f309ea2265a454b8ca5", "intent_expiry": "2022-11-15 12:34:34" } ``` -------------------------------- ### Java Example: Process QFPay Payment Request Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/in-store/CPM This Java example shows how to prepare payment parameters, generate a signature using MD5, and send a POST request to the QFPay payment API. It includes setting up transaction details, merchant ID, and handling date formatting. ```Java import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; public class TestMain { public static void main(String args[]){ String appcode="D5589D2A1F2E42A9A60C37*********"; String key="0E32A59A8B454940A2FF39*********"; String mchid="ZaMVg*****"; String pay_type="800108"; String auth_code="280438849930815813"; String out_trade_no= "01234567890123"; SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String date=df.format(new Date()); String txdtm=date; String txamt="10"; String txcurrcd="EUR"; Map unsortMap = new HashMap<>(); unsortMap.put("mchid", mchid); unsortMap.put("pay_type", pay_type); unsortMap.put("auth_code", auth_code); unsortMap.put("out_trade_no", out_trade_no); unsortMap.put("txdtm", txdtm); unsortMap.put("txamt", txamt); unsortMap.put("txcurrcd", txcurrcd); //unsortMap.put("product_name", product_name); //unsortMap.put("valid_time", "300"); String data=QFPayUtils.getDataString(unsortMap); System.out.println("Data:\n"+data+key); String md5Sum=QFPayUtils.getMd5Value(data+key); System.out.println("Md5 Value:\n"+md5Sum); String url="https://test-openapi-hk.qfapi.com"; String resp= Requests.sendPostRequest(url+"/trade/v1/payment", data, appcode,key); System.out.println(resp); } } ``` -------------------------------- ### PHP Example: Initiate QFPay Payment with Random String Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/in-store/CPM This PHP example demonstrates how to prepare payment parameters for a QFPay transaction, including generating a random string for the `out_trade_no`. It sets up the API endpoint, payment type, authorization code, and API credentials, preparing the data for a POST request. ```PHP urlencode($mchid), 'pay_type' => urlencode($pay_type), 'auth_code' => urlencode($auth_code), 'out_trade_no' => urlencode(GetRandStr(20)), 'txcurrcd' => urlencode('HKD'), ``` -------------------------------- ### Initiate Trade Reversal API Request Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/common-api/reversal-cancel This section provides code snippets in various languages to demonstrate how to initiate a trade reversal request to the QFPay API. Each example covers the construction of the request payload with transaction details, the generation of the required signature, and sending a POST request to the `/trade/v1/reversal` endpoint. The examples highlight parameter sorting and MD5 hashing for signature creation. ```Python txamt = '2500' #In USD,EUR,etc. Cent. Suggest value > 200 to avoid risk control out_trade_no = '4MDGEJ7L496LAAU1V1HBY9HMOGWZWLXQ' syssn = '20200305066100020000977812' txdtm = '2020-03-05 16:50:30' mchid = 'MNxMp11FV35qQN' key = client_key data ={'txamt': txamt, 'out_trade_no': out_trade_no, 'txdtm': txdtm, 'mchid': mchid} r = requests.post(environment+"/trade/v1/reversal",data=data,headers={'X-QF-APPCODE':app_code,'X-QF-SIGN':make_req_sign(data, key)}) print(r.json()) ``` ```Java import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; public class Refund { public static void main(String args[]){ String appcode="3F504C39125E4886AB4741**********"; String key="5744993FBC034DBBB995FA**********"; String mchid="MNxMp11FV35qQN"; // Only Agents must provide the mchid SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String date=df.format(new Date()); String txdtm="2020-03-05 16:50:30"; String txamt="2500"; String syssn="20200305066100020000977812"; //only syssn or out_trade_no must be provided String out_trade_no="4MDGEJ7L496LAAU1V1HBY9HMOGWZWLXQ"; //only syssn or out_trade_no must be provided Map unsortMap = new HashMap<>(); unsortMap.put("mchid", mchid); unsortMap.put("txamt", txamt); unsortMap.put("syssn", syssn); unsortMap.put("out_trade_no", out_trade_no); unsortMap.put("txdtm", txdtm); String data=QFPayUtils.getDataString(unsortMap); System.out.println("Data:\n"+data+key); String md5Sum=QFPayUtils.getMd5Value(data+key); System.out.println("Md5 Value:\n"+md5Sum); //如果是国内钱台,网址是:https://test-openapi-hk.qfapi.com. String url="https://test-openapi-hk.qfapi.com"; String resp= Requests.sendPostRequest(url+"/trade/v1/reversal", data, appcode,key); System.out.println(resp); } } ``` ```JavaScript // Enter Client Credentials environment = 'https://test-openapi-hk.qfapi.com' app_code = '3F504C39125E4886AB4741**********' client_key = '5744993FBC034DBBB995FA**********' // Generate Timestamp var dateTime = new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '') console.log(dateTime) // Body Payload const key = client_key var tradenumber = String(Math.round(Math.random() * 1000000000)) console.log(tradenumber) var payload = { 'txamt': '2500', 'out_trade_no': '4MDGEJ7L496LAAU1V1HBY9HMOGWZWLXQ', //only syssn or out_trade_no must be provided 'syssn': '20200305066100020000977812', //only syssn or out_trade_no must be provided 'txdtm': '2020-03-05 16:50:30', 'mchid': 'MNxMp11FV35qQN' }; // Signature Generation const ordered = {}; Object.keys(payload).sort().forEach(function(key) { ordered[key] = payload[key] }); console.log(ordered) var str = []; for (var p in ordered) if (ordered.hasOwnProperty(p)) { str.push((p) + "=" + (ordered[p])); } var string = str.join("&")+client_key; console.log(string) const crypto = require('crypto') var hashed = crypto.createHash('md5').update(string).digest('hex') console.log(hashed) // API Request var request = require("request"); request({ uri: environment+"/trade/v1/reversal", headers: { 'X-QF-APPCODE': app_code, 'X-QF-SIGN': hashed }, method: "POST", form: payload, }, function(error, response, body) { console.log(body); }); ``` ```PHP urlencode($mchid), 'syssn' => urlencode($syssn), //'out_trade_no' => urlencode($out_trade_no), 'txcurrcd' => urlencode('HKD'), 'txamt' => urlencode(2200), 'txdtm' => date('2020-03-05 16:50:30') ); ksort($fields); //Sort parameters in ascending order from A to Z print_r($fields); foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&' ; } $fields_string = substr($fields_string , 0 , strlen($fields_string) - 1); $sign = strtoupper(md5($fields_string . $app_key)); //// Header //// $header = array(); $header[] = 'X-QF-APPCODE: ' . $app_code; $header[] = 'X-QF-SIGN: ' . $sign; //Post Data $ch = curl_init(); ``` -------------------------------- ### Example API JSON Response Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/preparation/introduction This snippet shows an example of a JSON response returned by the API, which in this case contains a single string value, likely representing a unique identifier or a status code. ```JSON { "B3B251B202801388BE4AC8E5537B81B1" } ``` -------------------------------- ### Process Refund in Java Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/common-api/refunds This Java example demonstrates how to prepare a refund request. It initializes API credentials, constructs a map of request parameters, formats the date, generates an MD5 signature, and sends a POST request to the QFPay refund endpoint. ```Java import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; public class Refund { public static void main(String args[]){ String appcode="D5589D2A1F2E42A9A60C37**********"; String key="0E32A59A8B454940A2FF39**********"; String mchid="ZaMVg*****"; // Only Agents must provide the mchid String out_trade_no= "22333444455555"; SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String date=df.format(new Date()); String txdtm=date; String txamt="15"; String syssn="20191227000300020061662295"; //如果是国内钱台,产品名称对应的字段是goods_name,不是product_name. //String product_name="Test Name"; Map unsortMap = new HashMap<>(); unsortMap.put("mchid", mchid); unsortMap.put("txamt", txamt); unsortMap.put("syssn", syssn); unsortMap.put("out_trade_no", out_trade_no); unsortMap.put("txdtm", txdtm); String data=QFPayUtils.getDataString(unsortMap); System.out.println("Data:\n"+data+key); String md5Sum=QFPayUtils.getMd5Value(data+key); System.out.println("Md5 Value:\n"+md5Sum); //如果是国内钱台,网址是:https://test-openapi-hk.qfapi.com. String url="https://test-openapi-hk.qfapi.com"; String resp= Requests.sendPostRequest(url+"/trade/v1/refund", data, appcode,key); System.out.println(resp); } } ``` -------------------------------- ### Sample API Response for Subscription Query Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/online-shop/qfpay-recurring-payment An example JSON structure for a successful API response, specifically for the `subscription/v1/query` endpoint, showing common response parameters and a list of subscription data. ```JSON { "resperr": "success", "respcd": "0000", "respmsg": "success", "data": [ { "total_billing_cycles": 3, "last_billing_time": "2024-11-21T11:12:06Z", "is_available": 1, "userid": 2510351, "last_billing_status": "SUCCESS", "state": "ACTIVE", "products": [ { "product_id": "prod_8efecd0bd******b9aa1ec5ec01", "quantity": 1 } ], "retry_attempts": 0, "completed_iteration": 1, "token_id": "tk_9ac510017*******69b614e8f7ee", "subscription_id": "sub_e120378de*******da066f690da75", "customer_id": "cust_5ba1539f*******c9bda11d12c854e36", "next_billing_time": "2024-11-21T11:13:06Z" } ] } ``` -------------------------------- ### Initiate Payment Pre-Authorisation Request Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/preparation/paycode This section provides multi-language code examples demonstrating how to construct the request payload, generate the necessary signature, and send a POST request to the '/trade/v1/payment' endpoint for initiating an online payment pre-authorisation. ```Python # Body payload txamt = '10' #In USD,EUR,etc. Cent. Suggest value > 200 to avoid risk control. txcurrcd = 'HKD' pay_type = '800101' # Alipay CPM = 800108 , MPM = 800101 auth_code='283854702356157409' #CPM only out_trade_no = '01234567890123' txdtm = current_time goods_name = 'test1' auth_code = '280438849930815813' mchid = 'ZaMVg*****' notify_url = 'https://xxx.com/notify/success' key = client_key #data ={'txamt': txamt, 'txcurrcd': txcurrcd, 'pay_type': pay_type, 'out_trade_no': out_trade_no, 'txdtm': txdtm, 'goods_name': goods_name, 'udid': udid, 'auth_code': auth_code, 'mchid': mchid, 'notify_url': notify_url} data ={'txamt': txamt, 'txcurrcd': txcurrcd, 'pay_type': pay_type, 'out_trade_no': out_trade_no, 'txdtm': txdtm, 'mchid': mchid} r = requests.post(environment+"/trade/v1/payment",data=data,headers={'X-QF-APPCODE':app_code,'X-QF-SIGN':make_req_sign(data, key)}) print(r.json()) ``` ```Java import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; public class TestMain { public static void main(String args[]){ String appcode="D5589D2A1F2E42A9A60C37*********"; String key="0E32A59A8B454940A2FF39*********"; String mchid="ZaMVg*****"; String pay_type="800101"; String out_trade_no= "01234567890123"; SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String date=df.format(new Date()); String txdtm=date; String txamt="10"; String txcurrcd="EUR"; Map unsortMap = new HashMap<>(); unsortMap.put("mchid", mchid); unsortMap.put("pay_type", pay_type); unsortMap.put("out_trade_no", out_trade_no); unsortMap.put("txdtm", txdtm); unsortMap.put("txamt", txamt); unsortMap.put("txcurrcd", txcurrcd); //unsortMap.put("product_name", product_name); //unsortMap.put("valid_time", "300"); String data=QFPayUtils.getDataString(unsortMap); System.out.println("Data:\n"+data+key); String md5Sum=QFPayUtils.getMd5Value(data+key); System.out.println("Md5 Value:\n"+md5Sum); String url="https://test-openapi-hk.qfapi.com"; String resp= Requests.sendPostRequest(url+"/trade/v1/payment", data, appcode,key); System.out.println(resp); } } ``` ```JavaScript // Enter Client Credentials const environment = 'https://test-openapi-hk.qfapi.com' const app_code = 'D5589D2A1F2E42A9A60C37*********' const client_key = '0E32A59A8B454940A2FF39*********' // Generate Timestamp var dateTime = new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '') console.log(dateTime) // Body Payload const key = client_key var tradenumber = String(Math.round(Math.random() * 1000000000)) console.log(tradenumber) var payload = { 'txamt': '10', // In USD,EUR,etc. Cent. Suggest value > 200 to avoid risk control. 'txcurrcd': 'HKD', 'pay_type': '800101', // Alipay CPM = 800108 , MPM = 800101 'out_trade_no': tradenumber, 'txdtm': dateTime, 'mchid': 'ZaMVg*****' }; // Signature Generation const ordered = {}; Object.keys(payload).sort().forEach(function(key) { ordered[key] = payload[key] }); console.log(ordered) var str = []; for (var p in ordered) if (ordered.hasOwnProperty(p)) { str.push((p) + "=" + (ordered[p])); } var string = str.join("&")+client_key; console.log(string) const crypto = require('crypto') var hashed = crypto.createHash('md5').update(string).digest('hex') console.log(hashed) // API Request var request = require("request"); request({ uri: environment+"/trade/v1/payment", headers: { 'X-QF-APPCODE': app_code, 'X-QF-SIGN': hashed }, method: "POST", form: payload, }, function(error, response, body) { console.log(body); }); ``` ```PHP urlencode($mchid), 'pay_type' => urlencode($pay_type), 'out_trade_no' => urlencode(GetRandStr(20)), 'txcurrcd' => urlencode('HKD'), 'txamt' => urlencode(2200), 'txdtm' => $now_time ); ksort($fields); //Ascending dictionary sorting A-Z print_r($fields); foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&' ; } $fields_string = substr($fields_string , 0 , strlen($fields_string) - 1); $sign = strtoupper(md5($fields_string . $app_key)); //// Header //// ``` -------------------------------- ### Transaction Notes API Response Example Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/common-api/transaction-note Example of the JSON response returned after successfully adding a note to a transaction. ```JSON { "resperr": "Success", "respcd": 0000, "respmsg": "", "data": { "syssn": "20190722000200020081084545" } } ``` -------------------------------- ### Unfreeze Pre-Authorised Transaction Response Example Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/online-shop/online-pre-authorisation Example JSON response for a successful unfreeze operation on a pre-authorised transaction, showing transaction details, amounts, and status codes. ```JSON { "sysdtm": "2024-02-26 17:17:05", "paydtm": "2024-02-26 17:17:06", "udid": "qiantai2", "txcurrcd": "HKD", "txdtm": "2024-02-26 09:17:05", "txamt": "2000", "resperr": "交易成功", "respmsg": "Void received", "out_trade_no": "", "syssn": "20240226180500020000014222", "orig_syssn": "20240226180500020000014220", "respcd": "0000", "chnlsn": "", "cardcd": "" } ``` -------------------------------- ### Python Asynchronous Notification Signature Verification Setup Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/common-api/asynchronous-notification This Python snippet provides the initial setup for verifying the signature of an asynchronous notification from QFPay. It demonstrates importing the `hashlib` and `json` libraries and defining the `client_key` required for the MD5 hashing process, which is appended to the raw request body before hashing. ```Python import hashlib import json # Client Credentials client_key = "3ABB1BFFE2E0497BB9270978B0BXXXXX" ``` -------------------------------- ### Example QFAPI Response Format Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/in-store/pos-api/ECR Illustrates a typical JSON response structure from the QFAPI, showing common fields like response code, data, and messages. ```JSON {"respcd": "6000","data": "{\"aaaaaa\"}","respmsg": "xxxxxxxxxx","resperr":"xxxxxxxxxx"} ``` -------------------------------- ### Python Example for Refund Request Signature Generation Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/common-api/refunds This Python code snippet demonstrates how to set up client credentials, generate dynamic parameter values, and create the required X-QF-SIGN for API requests. It includes a utility function for MD5 hashing to ensure data integrity and authentication. ```Python import urllib.request, urllib.parse, urllib.error, urllib.request, urllib.error, urllib.parse, hashlib import requests from hashids import Hashids import datetime import string import random # Enter Client Credentials environment = 'https://test-openapi-hk.qfapi.com' app_code = 'D5589D2A1F2E42A9A60C37**********' client_key = '0E32A59A8B454940A2FF39**********' # Create parameter values for data payload current_time = datetime.datetime.now().replace(microsecond=0) random_string = ''.join(random.choices(string.ascii_uppercase + string.digits, k=32)) # Create signature def make_req_sign(data, key): keys = list(data.keys()) keys.sort() p = [] for k in keys: v = data[k] p.append('%s=%s'%(k,v)) unsign_str = ('&'.join(p) + key).encode("utf-8") s = hashlib.md5(unsign_str).hexdigest() return s.upper() ``` -------------------------------- ### Transaction Notification Example JSON Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/online-shop/online-pre-authorisation Example JSON structure for various transaction notifications (payment, unfreeze, refund), detailing status, transaction amounts, IDs, and the notification type. ```JSON { "status": "1", "pay_type": "800101", "sysdtm": "2020-05-14 12:32:56", "paydtm": "2020-05-14 12:33:56", "goods_name": "", "txcurrcd": "HKD", "txdtm": "2020-05-14 12:32:56", "mchid": "", "txamt": "10", "exchange_rate": "", "chnlsn2": "", "out_trade_no": "YEPE7WTW46NVU30JW5N90H7DHD94N56B", "syssn": "20200514000300020093755455", "cash_fee_type": "", "cancel": "0", "respcd": "0000", "goods_info": "", "cash_fee": "0", "notify_type": "payment", "chnlsn": "", "cardcd": "" } ``` -------------------------------- ### Example MD5 Signature String Output Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/common-api/asynchronous-notification This snippet provides an example of a generated MD5 signature string, illustrating the expected format of the output after performing the signature calculation on asynchronous notification data. ```Text "A4021A3B1EBBB0F05451EF94E9EXXXXX" ``` -------------------------------- ### Perform Refund Operation in JavaScript Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/common-api/refunds This JavaScript example demonstrates how to set up client credentials, generate a timestamp, construct the request payload, sort parameters for signature generation, compute the MD5 hash, and send a POST request using the `request` module to the QFPay refund API. ```JavaScript // Enter Client Credentials const environment = 'https://test-openapi-hk.qfapi.com' const app_code = 'D5589D2A1F2E42A9A60C37**********' const client_key = '0E32A59A8B454940A2FF3***********' // Generate Timestamp var dateTime = new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '') console.log(dateTime) // Body Payload const key = client_key var tradenumber = String(Math.round(Math.random() * 1000000000)) console.log(tradenumber) var payload = { 'syssn': '20191231000300020063521806', 'txamt': '10', 'out_trade_no': tradenumber, 'txdtm': dateTime, 'mchid': 'ZaMVg*****' }; // Signature Generation const ordered = {}; Object.keys(payload).sort().forEach(function(key) { ordered[key] = payload[key] }); console.log(ordered) var str = []; for (var p in ordered) if (ordered.hasOwnProperty(p)) { str.push((p) + "=" + (ordered[p])); } var string = str.join("&")+client_key; console.log(string) const crypto = require('crypto') var hashed = crypto.createHash('md5').update(string).digest('hex') console.log(hashed) // API Request var request = require("request"); request({ uri: environment+"/trade/v1/refund", headers: { 'X-QF-APPCODE': app_code, 'X-QF-SIGN': hashed }, method: "POST", form: payload, }, function(error, response, body) { console.log(body); }); ``` -------------------------------- ### Execute Refund Request in PHP Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/common-api/refunds This PHP example demonstrates how to implement a refund request. It includes a helper function for generating random strings, sets up API credentials, prepares and sorts the request parameters, generates the MD5 signature, and sends the POST request using cURL. ```PHP urlencode($mchid), 'syssn' => urlencode($syssn), 'out_trade_no' => urlencode(GetRandStr(20)), 'txamt' => urlencode(2200), 'txdtm' => $now_time ); ksort($fields); //Sort parameters in ascending order from A to Z print_r($fields); foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&' ; } $fields_string = substr($fields_string , 0 , strlen($fields_string) - 1); $sign = strtoupper(md5($fields_string . $app_key)); //// Header //// $header = array(); $header[] = 'X-QF-APPCODE: ' . $app_code; $header[] = 'X-QF-SIGN: ' . $sign; //Post Data $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url . $api_type); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ``` -------------------------------- ### Example QFPay Response for Pre-Authorisation Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/online-shop/alipay/alipay-in-app-payments Illustrates the structure and content of a successful QFPay response, including transaction details and 'pay_params' for Alipay SDK integration. ```JSON { "pay_type": "801510", "sysdtm": "2021-05-27 11:57:02", "paydtm": "2021-05-27 11:57:02", "udid": "qiantai2", "txcurrcd": "HKD", "txdtm": "2021-05-27 11:57:00", "txamt": "1", "resperr": "交易成功", "respmsg": "", "out_trade_no": "052711570017898", "syssn": "20210527154100020004180921", "pay_params": { "body": "goods_info", "forex_biz": "FP", "seller_id": "2088231067382451", "secondary_merchant_id": "1000007081", "service": "mobile.securitypay.pay", "payment_inst": "ALIPAYHK", "it_b_pay": "30m", "secondary_merchant_name": "IFlare Hong Kong Limited (external) - online", "_input_charset": "UTF-8", "sign": "iU1yXUnsCK7rJAu0DoN61arVexbIfo3GLR5jr3QzjkZ29INSPhcA4e%2F2%2BdPrsf5huzQAkxVKP0CTfvaGPMYqNkxmhoaJWUH0ZhgYDgKugMvtweBvRqOX2W0h3A%2F%2FIdJuxeyOAuh7bHiuazSB3ZH%2BEQwRGP%2Bkk8Jpha930gHwPtw%3D", "currency": "HKD", "out_trade_no": "20210527154100020004180921", "payment_type": "1", "total_fee": 0.01, "sign_type": "RSA", "notify_url": "https://test-o2-hk.qfapi.com/trade/alipay_hk/v1/notify", "partner": "2088231067382451", "secondary_merchant_industry": "5941", "product_code": "NEW_WAP_OVERSEAS_SELLER", "return_url": "https://www.qfpay.global/", "subject": "goods_name" }, "respcd": "0000", "chnlsn": "", "cardcd": "" } ``` -------------------------------- ### MPM API Request Header and Body Example Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/in-store/MPM Provides an example of the HTTP request headers and the application/x-www-form-urlencoded request body for the Merchant Present Mode (MPM) payment API. It includes essential headers like Content-Type, X-QF-APPCODE, and X-QF-SIGN, along with key body parameters such as out_trade_no, pay_type, and txamt. ```APIDOC Request Header: { Content-Type: application/x-www-form-urlencoded; charset=UTF-8, Content-Length: 218, Chunked: false, X-QF-APPCODE: A6A49A66B4C********94EA95032, X-QF-SIGN: 3b020a6349646684ebeeb0ec2cd3d1fb } Request Body: { expired_time=10&goods_name=qfpay&limit_pay=no_credit&mchid=R1zQrTdJnn&out_trade_no=Native20190722145741431794b8d1&pay_type=800201&txamt=20&txcurrcd=HKD&txdtm=2019-07-22 14:57:42&udid=AA } ``` -------------------------------- ### Example JSON Response for Pre-Authorization API Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/in-store/CPM This JSON object illustrates a typical successful response from the pre-authorization API, including transaction details such as payment type, system date/time, transaction amount, and response codes. ```JSON { "pay_type": "800108", "sysdtm": "2019-07-22 15:20:54", "paydtm": "2019-07-22 15:20:56", "txdtm": "2019-07-22 15:20:54", "udid": "AA", "txcurrcd": "EUR", "txamt": 10, "resperr": "交易成功", "respmsg": "OK", "out_trade_no": "201907221520536a25477909", "syssn": "20190722000300020081074842", "respcd": "0000", "chnlsn": "4200000384201907223585006133" } ``` -------------------------------- ### Example JSON Response for QFPay Payment Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/preparation/paycode This JSON object illustrates a typical successful response structure from the QFPay payment API. It includes transaction details such as time, QR code, payment type, amounts, and system identifiers. ```JSON { "txdtm": "2019-12-25 14:21:28", "qrcode": "https://qr.alipay.com/bax01781r3pu4fjaqazt4091", "pay_type": "800101", "resperr": "success", "out_trade_no": "01234567890123", "syssn": "20191225000200020060996533", "sysdtm": "2019-12-25 14:22:37", "paydtm": "2019-12-25 14:22:37", "txcurrcd": "EUR", "respmsg": "", "cardcd": "", "udid": "qiantai2", "txamt": "10", "respcd": "0000", "chnlsn": "" } ``` -------------------------------- ### Initiate QFPay Payment Pre-authorisation (Java) Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/in-store/MPM This Java example shows how to build a payment request map, format the transaction date, and use QFPayUtils to generate the data string and MD5 signature. It then sends a POST request to the QFPay payment API endpoint. ```Java import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; public class TestMain { public static void main(String args[]){ String appcode="D5589D2A1F2E42A9A60C37*********"; String key="0E32A59A8B454940A2FF39*********"; String mchid="ZaMVg*****"; String pay_type="800101"; String out_trade_no= "01234567890123"; SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String date=df.format(new Date()); String txdtm=date; String txamt="10"; String txcurrcd="EUR"; Map unsortMap = new HashMap<>(); unsortMap.put("mchid", mchid); unsortMap.put("pay_type", pay_type); unsortMap.put("out_trade_no", out_trade_no); unsortMap.put("txdtm", txdtm); unsortMap.put("txamt", txamt); unsortMap.put("txcurrcd", txcurrcd); //unsortMap.put("product_name", product_name); //unsortMap.put("valid_time", "300"); String data=QFPayUtils.getDataString(unsortMap); System.out.println("Data:\n"+data+key); String md5Sum=QFPayUtils.getMd5Value(data+key); System.out.println("Md5 Value:\n"+md5Sum); String url="https://test-openapi-hk.qfapi.com"; String resp= Requests.sendPostRequest(url+"/trade/v1/payment", data, appcode,key); System.out.println(resp); } } ``` -------------------------------- ### Initiate QFPay Payment Pre-authorisation (PHP) Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/in-store/MPM This PHP example demonstrates how to set up the necessary parameters for a QFPay payment request, including generating a random trade number and current timestamp. It shows how to sort the request fields alphabetically and construct the URL-encoded query string for signature generation. ```PHP urlencode($mchid), 'pay_type' => urlencode($pay_type), 'out_trade_no' => urlencode(GetRandStr(20)), 'txcurrcd' => urlencode('HKD'), 'txamt' => urlencode(2200), 'txdtm' => $now_time ); ksort($fields); //Ascending dictionary sorting A-Z print_r($fields); foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&' ; } $fields_string = substr($fields_string , 0 , strlen($fields_string) - 1); ``` -------------------------------- ### API Payment Request Header and Body Example Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/preparation/paycode Illustrates the structure of an API payment request, including the necessary Content-Type header, authentication headers (X-QF-APPCODE, X-QF-SIGN), and the URL-encoded body parameters such as mchid, out_trade_no, pay_type, txamt, txcurrcd, and txdtm. ```APIDOC Request Header: { Content-Type: application/x-www-form-urlencoded; X-QF-APPCODE: D5589D2A1F2E42A9A60C37********** X-QF-SIGN: 6FB43AC29175B4602FF95F8332028F19 } Request Body: { mchid=ZaMVg*****&out_trade_no=01234567890123&pay_type=800101&txamt=10&txcurrcd=EUR&txdtm=2019-12-25 14:21:28 } ``` -------------------------------- ### Example JSON Response for QFPay Transaction Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/common-api/reversal-cancel This JSON structure illustrates a typical successful response from a QFPay transaction API call. It includes details such as surcharge fees, transaction time, system serial number, currency, response codes, and transaction amounts. ```JSON { "surcharge_fee": "0", "resperr": "success", "txdtm": "2020-03-05 16:50:30", "syssn": "20200305066100020000977814", "sysdtm": "2020-03-05 16:54:38", "txcurrcd": "EUR", "respmsg": "", "chnlsn2": "", "cardcd": "", "udid": "qiantai2", "txamt": "2500", "orig_syssn": "20200305066100020000977813", "surcharge_rate": "0", "respcd": "0000", "chnlsn": "" } ``` -------------------------------- ### Example Redirect URL After Successful OAuth Code Request Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/online-shop/wechat/wechat-pay-jsapi This snippet provides an example of the URL to which the user is redirected after a successful GET oauth_code request. It includes the code parameter, which is the WeChat oauth_code needed for subsequent API calls. ```URL http://xg.fshop.top/index.php/wap/pay/wxredirect?showwxpaytitle=1&code=011QipnO1yMIla1VJdoO1FUrnO1Qipnv ``` -------------------------------- ### WeChat OpenID Request URL Example Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/online-shop/wechat/wechat-pay-jsapi This snippet shows the structure of the GET request URL to obtain the WeChat openid. It includes the code parameter, which is the oauth_code obtained from the previous step. ```URL https://test-openapi-hk.qfapi.com/tool/v1/get_weixin_openid?code=011QipnO1yMIla1VJdoO1FUrnO1Qipnv ``` -------------------------------- ### Initialize QFPay Element SDK for Credit Card Form (Visa/Mastercard) Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/online-shop/paymentelement This JavaScript code demonstrates how to initialize the QFPay SDK, set up a payment object with basic parameters, and generate a credit card form using `elements.createEnhance`. It also shows how to trigger the form submission and receive the payment response. ```JavaScript // initialize qfpay object const qfpay = QFpay.config() // initialize payment object const payment = qfpay.payment() // set payment related parameters payment.pay({ goods_name: "goods", paysource: "payment_element" }, "e487a02e3e1143e482db765ccec63d58") // initialize element object and generate card form const elements = qfpay.element() elements.createEnhance({ selector: "#container" }) // trigger card form submission and receive payment response const response = qfpay.confirmPayment({ return_url: 'https://xxx.xxx.com' }) ``` -------------------------------- ### WeChat OAuth Code Request URL Example Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/online-shop/wechat/wechat-pay-jsapi This snippet shows the structure of the GET request URL to obtain the WeChat oauth_code. It includes placeholder parameters for app_code, sign, and redirect_uri. ```URL https://test-openapi-hk.qfapi.com/tool/v1/get_weixin_oauth_code?app_code=5D81D64E602043F7AF51CEXXXXXXXXXX&sign=F4D8FB00894F213993B33116BC1B4E10&redirect_uri=https://sdk.qfapi.com ``` -------------------------------- ### Initialize QFPay Element SDK for Complete Payment Function (WalletPay) Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/online-shop/paymentelement This JavaScript example illustrates how to use the QFPay SDK for a comprehensive payment solution, including various wallet payments (Alipay, WeChat, UnionPay, etc.) and credit card pre-authorization. It initializes the SDK, sets payment parameters, creates a wallet list UI, and confirms the payment. ```JavaScript // initialize qfpay object const qfpay = QFpay.config() // initialize payment object const payment = qfpay.payment() // validate payment intent valye qfpay.retrievePaymentIntent() // set payment parameters payment.walletPay( { lang: 'zh-cn', goods_info: 'goods_info', goods_name: "goods_name", paysource: "payment_element_checkout", out_trade_no: intentParams.out_trade_no, txamt: intentParams.txamt, txcurrcd: intentParams.txcurrcd, support_pay_type: ['Alipay', 'WeChat', 'UnionPay', 'AlipayHK', 'FPS', 'VisaMasterCardPayment', 'ApplePay', 'VisaMasterCardPreAuth'] },intentParams.payment_intent); // initalize element object and create wallet list const appearance = { variables: { colourComponentText: 'black', colorQRCodeTopPromptContent: '#000000', colorQRCodeBottomPromptContent: '#000000', fontWeightQRCodeTopPrompt: '900', fontWeightQRCodeBottomPrompt: '300' }, billingAddressDisplay: { city: true, address1: true, address2: true, } } const elements = qfpay.element(appearance) elements.createWallet({ selector: "#container" }) //trigger submission and retrieve payment response const response = qfpay.confirmWalletPayment({ return_url: 'https://xxx.xxx.com' }) ``` -------------------------------- ### Example JSON Response for WeChat OpenID Request Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/online-shop/wechat/wechat-pay-jsapi This snippet illustrates the expected JSON structure returned by the GET openid API call. It includes fields like respcd for response code, resperr for error messages, and openid containing the unique WeChat user identifier. ```JSON { "resperr": "", "respcd": 0000, "respmsg": "", "openid": "oo3Lss8d0hLOuyTuSJMVwLTk68JE" } ``` -------------------------------- ### Transaction Notes API Request Example Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/common-api/transaction-note Example of the HTTP request headers and body required to add a note to a transaction. ```HTTP Request Header: { Content-Type: application/x-www-form-urlencoded; X-QF-APPCODE: D5589D2A1F2E42A9A60C37********** X-QF-SIGN: 6FB43AC29175B4602FF95F8332028F19 } Request Body: { code=A6A49A6******DFE94EA95032¬e=add_note&syssn=20190722000200020081075691 } ``` -------------------------------- ### QFPay Element SDK Prerequisites Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/online-shop/paymentelement This section outlines the prerequisites for using the QFPay Element SDK, specifically emphasizing the need to import the SDK library (`qfpay.js`) based on the intended environment and purpose. ```Text Prerequisites: import SDK library (qfpay.js) according to your environment and purpose ``` -------------------------------- ### WeChat Pay H5: Example pay_url Response Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/online-shop/wechat/wechat-pay-h5 An example of the `pay_url` returned in the payment response, which is used for user redirection. A note explains how to append a `redirect_url`. ```APIDOC https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx20161110163838f231619da20804912345&package=1037687096 ``` -------------------------------- ### PHP Example: Constructing and Sending a Pre-Authorization API Request Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/in-store/CPM This PHP code demonstrates how to prepare the request parameters, sort them, generate a signature using MD5 and an application key, construct HTTP headers, and send a POST request to the API endpoint using cURL. It also shows how to decode the JSON response. ```PHP 'txamt' => urlencode(2200), 'txdtm' => $now_time ); ksort($fields); //Ascending dictionary sorting A-Z print_r($fields); foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&' ; } $fields_string = substr($fields_string , 0 , strlen($fields_string) - 1); $sign = strtoupper(md5($fields_string . $app_key)); //// Header //// $header = array(); $header[] = 'X-QF-APPCODE: ' . $app_code; $header[] = 'X-QF-SIGN: ' . $sign; //Post Data $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url . $api_type); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); $output = curl_exec($ch); curl_close($ch); $final_data = json_decode($output, true); print_r($final_data); ob_end_flush(); ?> ``` -------------------------------- ### API Reference: GET WeChat OAuth Code Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/online-shop/wechat/wechat-pay-jsapi Detailed API documentation for the GET /tool/v1/get_weixin_oauth_code endpoint. It specifies the method, required parameters, their types, and descriptions for obtaining the WeChat oauth_code. ```APIDOC Endpoint: /tool/v1/get_weixin_oauth_code Method: GET Description: Both the app_code and sign have to be submitted as parameters instead of in the http header. The URL request has to be send in the WeChat environment. Everytime a payment is initiated the WeChat oauth_code and openid have to be obtained again. Request Parameters: - app_code: - Mandatory: Yes - Type: String(32) - Description: Developer ID, the app_code is assigned to partners by QFPay - redirect_uri: - Mandatory: Yes - Type: String(512) - Description: Callback URL, after the request has been successful the user will be redirected to the callback address - mchid: - Mandatory: No - Type: String(16) - Description: Merchant ID, the mchid is a unique identification for every merchant assigned by QFPay - sign: - Mandatory: Yes - Type: String - Description: Signature obtained according to the unified framework ``` -------------------------------- ### Python Example: Initiate QFPay Payment Request Source: https://sdk.qfapi.com/docs/online-shop/online-pre-authorisation/in-store/CPM This Python snippet demonstrates how to construct the payload for a QFPay payment request, including transaction details like amount, currency, payment type, and authorization code. It then sends a POST request to the QFPay API endpoint with the necessary headers for authentication and signature. ```Python txamt = '10' #In USD,EUR,etc. Cent. Suggest value > 200 to avoid risk control. txcurrcd = 'HKD' pay_type = '800108' # Alipay CPM = 800108 , WeChat Pay CPM = 800208 auth_code = '280438849930815813' # Mandatory for CPM out_trade_no = '01234567890123' txdtm = current_time goods_name = 'test1' mchid = 'ZaMVg*****' notify_url = 'https://xxx.com/notify/success' key = client_key #data ={'txamt': txamt, 'txcurrcd': txcurrcd, 'pay_type': pay_type, 'out_trade_no': out_trade_no, 'txdtm': txdtm, 'goods_name': goods_name, 'udid': udid, 'auth_code': auth_code, 'mchid': mchid, 'notify_url': notify_url} data ={'txamt': txamt, 'txcurrcd': txcurrcd, 'pay_type': pay_type, 'out_trade_no': out_trade_no, 'txdtm': txdtm, 'mchid': mchid, 'auth_code': auth_code} r = requests.post(environment+"/trade/v1/payment",data=data,headers={'X-QF-APPCODE':app_code,'X-QF-SIGN':make_req_sign(data, key)}) print(r.json()) ```