QFPay API in Japanese Business
Index
● 1. Business Process
● 1.1 Merchant registration
● 1.2 Payment Process
○ 1.2.4 Response code description
● 1.3 Reconciliation
● 2. API
● 2.2 Dynamic QR code pay interface
● 2.6 Download reconciliation interface
Merchants have to register to the QFPay services.
After registration, merchants will receive their app-code, key for integration, and the unique merchant ID (mchid) for each store.
Example:
AppCode: <32_character_MD5_string_qfpay>
Key: <32_character_MD5_string_qfpay>
Now, we provide an example about how merchants can use the API to do a barcode payment.
Note: There are limitations to the payment amount (depending on bank). Please refer to kf.qq.com/touch/sappfaq/151210NZzmuY151210ZRj2y2.html?platform=15&ADTAG=veda.weixinpay.wenti
After receiving the code, key and mchid, merchants are ready to use the QFPay services. By using code scanner, Merchant can scan consumer's Wechat/Alipay QR code to get the auth_code, cash will be deducted from consumer's Wechat/Alipay account. The whole process is shown as the following flow chart
Process:
Step 1, using code scanner to scan consumer's Wechat/Alipay QR code, send the transaction request to QFPay system. (The detail of the barcode payment interface can be found at API 2.1)
1a, if get response code as 0000 from the QFPay system, then the transaction is successful.
1c, if get response code which is not 0000, 1143 or 1145, then the transaction is failed.
1b, if get response code as 1143, 1145 from the QFPay system, then the transaction is still in processing.
Step 2, call the query interface to QFPay system and check the status of the transaction again.
(The detail of the query interface can be found at API 2.4)
2a, if get response code as 0000 from the QFPay system, then the transaction is successful.
2c, if get response code which is not 0000, 1143 or 1145, then the transaction is failed.
2b, if get response code as 1143, 1145 from the QFPay system, then the transaction is still in processing. Go back to Step 2.
After calling query interface for more than 2 minutes, if the response code is still 1143 or 1145, please cancel the transaction and place the order again.
(The detail of the cancel interface can be found at API 2.5)
Response code | Description |
0000 | Operation successful |
1147 | Wechat card failed | brushed Hong Kong wallet, does not support or password input error |
2007 | The consumer closed the transaction | the consumer needs to enter the password, but the consumer closes the password input box, causing the order to close. |
2006 | QR code is illegal; Alipay QR code was scanned by wechat; QR code is invalid |
1142 | The order has been closed | the merchant opened an order, then timed out and the order closed. |
1144 | Wechat pay QR code was scanned by Alipay Bank card binded is invalid. |
2004 | Insufficient account balance |
2005 | QR code is invalid | payment is made within one minute of the consumer opening the payment APP |
1142 | Order has been closed. |
1145 | Waiting for payment. |
1296 | Channel error (configuration error or Wechat is suspended) |
1297 | Please try other payment types | Configuration error, scaner side and payment side are the same Wechat user. |
1143 | "The order does not exist" , The refund channel request was not passed, resulting in no refund |
In this scenario, merchant can scan consumer's Wechat/Alipay QR code via scanning gun to get auth_code, cash will be deducted from consumer's Wechat/Alipay account
Method | HTTP Post |
Path | /trade/v1/payment |
Description | Merchants scan the QR code in the consumer’s smartphone. |
Parameter | Required | Definition | Description | Example |
txamt | Y | Int | Amount of payment: It is measured in the minimum price unit of the transaction currency. (Maximum 10,000 USD) | 1 |
txcurrcd | Y | String | Currency code: JPY | JPY |
pay_type | Y | String | Payment type: Wechat:800208;Alipay:800108; All-in-one swipe 800008; | 800208 |
Y | String No longer than 128 byte | Merchant's order number: The merchant’s order number has to be unique | 1469686389649 | |
txdtm | Y | String | Transaction time : format: YYYY-MM-DD HH:MM:SS | 2016-07-28 14:13:10 |
auth_code | Y | String(128) | Authentication code: The QR code shown from the user’s Wechat or Alipay | 120061098828009406 |
goods_name | Y | String No long than 20 byte | Name of the product: special character is not allowed | |
mchid | Y | String | Merchant id: allocate by QFPAY(You can look up merchant ID in Agent Management System) | BvDtmKJA5mx7GpN0 |
udid | N | UUID of device, no longer than 40 characters |
{'pay_type': '800201', 'out_trade_no': 755004603759, 'goods_name': '\xe9\x92\xb1\xe6\x96\xb9\xe6\xb5\x8b\xe8\xaf\x95', 'limit_pay': 'no_credit', 'udid': '1880105', 'txcurrcd': 'JPY', 'txdtm': '2018-07-20 04:11:11', 'mchid': '8w5pdhDJkm', ' txamt': 1} |
Parameter | Definition | Description | Example |
pay_type | String | Payment type: wechat: 800201;alipay: 800101; | 800201 |
sysdtm | String | System time | 2016-07-28 14:13:10 |
txdtm | String | Transaction time : format: YYYY-MM-DD HH:MM:SS | 2016-07-28 14:13:09 |
resperr | String | Information Description | success |
txcurrcd | String | Currency code: JPY | JPY |
txamt | Int | Amount of payment: It is measured in the minimum price unit of the transaction currency. | 10000 |
respmsg | String | Debug information | success |
String No longer than 128 byte | Merchant's order number | 1470020842103 | |
syssn | String | Order number in QFPAY system | 201607280901020011216135 |
String | Response code: 0000 stands for order placed successfully 1143,1145 stand for transaction in processing, merchant need to continue querying transaction. if other codes returned, transaction failed | 0000 | |
mchid | String | Merchant id: allocate by QFPAY(You can look up merchant ID in channel system) | BvDtmKJA5mx7GpN0 |
{"pay_type": "800208", "sysdtm": "2018-01-12 17:10:26", "cardcd":"oo3Lss-DzPSygtHtAbfuXeQFCz18", "txdtm": "2018-01-12 17:10:32", "resperr": "\u4ea4\u6613\u6210\u529f", "txcurrcd": "CNY", "txamt": "1", "respmsg": "", "out_trade_no":"1301459478787530052", "syssn":"20180112000100020001659358", "respcd": "0000"} |
Merchant enter the price of product and call QFPay’s interface to generate a dynamic QR code, consumer scan the QR code by using Wechat or Alipay app to finish the payment. The dynamic QR code will expire in 30 minutes.
Method | HTTP Post |
Path | /trade/v1/payment |
Description | Consumers scan the QR code from merchants. |
Parameter | Required | Definition | Description | Example |
txamt | Y | Int | Amount of payment: It is measured in the minimum price unit of the transaction currency. (Max 10,000 USD) | 10000 |
txcurrcd | Y | String | Currency code: JPY | JPY CNY |
pay_type | Y | String | Payment type: wechat: 800201;alipay: 800101; | 800201 |
Y | String No longer than 128 byte | Merchant's order number The merchant’s order number has to be unique | 1470020842103 | |
txdtm | Y | String | Transaction time: format: YYYY-MM-DD HH:MM:SS | 2016-08-01 11:07:22 |
Y | String | Name of the product | Cosmetics | |
mchid | Y | String | Merchant id: allocate by QFPAY(You can look up merchant ID in channel system) | BvDtmKJA5mx7GpN0 |
limit_pay | N | The value of this parameter can only be set to no_credit, which means credit is not allowed | ||
udid | N | UUID of device, no longer than 40 characters |
{'pay_type': '800208', 'out_trade_no': 725526999001L, 'goods_name': '\xe9\x92\xb1\xe6\x96\xb9\xe6\xb5\x8b\xe8\xaf\x95', 'limit_pay': 'no_credit', 'udid': '1880105', 'txcurrcd': 'JPY', 'auth_code': '134676275354204254', 'txdtm': '2018-07-20 04:27:18', 'mchid': '8w5pdhDJkm', 'txamt': 1} |
Parameter | Definition | Description | Example |
pay_type | String | Payment type: wechat: 800201;alipay: 800101; | 800201 |
sysdtm | String | System time | 2016-07-28 14:13:10 |
txdtm | String | Transaction time : format: YYYY-MM-DD HH:MM:SS | 2016-08-01 11:07:22 |
resperr | String | Information Description | |
txamt | String | Amount of payment: It is measured in the minimum price unit of the transaction currency. | 10000 |
respmsg | String | Debug information | |
String No longer than 128 byte | Merchant's order number | 1470020842103 | |
syssn | String | Order number in QFPAY system | 201607280901020011216135 |
qrcode | String | QR code url: merchant need to convert it to QR code image | weixin://wxpay/bizpayurl?pr=xxxxxxx |
String | Response code: 0000 stands for order placed successfully 1143,1145 stand for transaction on going, merchant need to continue querying transaction. if other codes returned, transaction failed | 1143 |
Merchants receive the notification callback when the payment is successfully made
Note: The notification callback may be delayed due to external factors. Therefore, please use query interface for the scene with real-time processing requirements. For security reasons, notification callback only supports ports 80 and 443, and custom port assignments are not supported. For more detail, please see Developer Guide 3.5.
The merchant and partner can use this interface to refund an existing payment. A refund can be partial and a transaction can have multiple refunds as long as the total refund amount is no greater than the original transaction amount.
Method | HTTP Post |
Path | /trade/v1/refund |
Description | The Payer will be refunded with the request refund amount. |
Parameter | Required | Definition | Description | Example |
txamt | Y | Int | Amount of payment: It is measured in the minimum price unit of the transaction currency. | 10000 |
syssn | Y | String | Order number in QFPAY system. It supports batch query, use "," to delimit multiple syssn numbers | 201607280901020011216135 |
Y | String No longer than 128 byte | Merchant's order number | 1470020842103 | |
txdtm | Y | String | Transaction time: format: YYYY-MM-DD HH:MM:SS | 2016-08-01 11:07:22 |
mchid | Y | String | Merchant id: allocate by QFPAY(You can look up merchant ID in channel system) | BvDtmKJA5mx7GpN0 |
udid | N | UUID of device, no longer than 40 characters |
{'txdtm': '2018-07-20 05:10:04', 'mchid': '8w5pdhDJkm', 'txamt': 1, 'out_trade_no': 428870566675L, 'syssn': '20180112000100020001661542'} } |
Parameter | Definition | Description | Example |
syssn | String | Refund order number in QFPAY system | 201607280901020011216135 |
orig_syssn | String | Original order number in QFPAY system | 20180112000100020001659358 |
sysdtm | String | System time | 2016-07-28 14:13:10 |
txdtm | String | Transaction time : format: YYYY-MM-DD HH:MM:SS | 2016-08-01 11:07:22 |
txamt | String | Amount of payment: It is measured in the minimum price unit of the transaction currency. | 10000 |
{"orig_syssn": "20180112000100020001659358", "sysdtm": "2018-01-12 19:03:23", "cardcd": "", "txdtm": "2018-01-12 19:03:29", "resperr": "\u4ea4\u6613\u6210\u529f", "txcurrcd": "JPY", "txamt": "1", "respmsg": "", "out_trade_no": "13014597435743348787530052", "syssn": "20180112000100020001661542", "respcd": "0000"} |
When the transaction is in processed, call the query interface to acquire the status of transaction. Using the start-time and end-time to check the status of transactions in multiple months. Or, using QFPay order number(syssn) to check the status of specific transaction.
Method | HTTP Post |
Path | /trade/v1/query |
Description | Query a transaction |
Parameter | Required | Definition | Description | Example |
mchid | Y | String | Merchant id: allocate by QFPAY(You can look up merchant ID in channel system) | BvDtmKJA5mx7GpN0 |
syssn | N | String | Order number in QFPAY system. It supports batch query, use "," to delimit multiple syssn numbers | 201607280901020011216135 |
N | String No longer than 128 byte | Merchant's order number | 1470020842103 | |
pay_type | N | String | Payment type: wechat: 800201;alipay: 800101; | 800201 |
N | String | Response code: 0000 stands for order placed successfully 1143,1145 stand for transaction on going, merchant need to continue querying transaction. if other codes returned, transaction failed | 0000 | |
start_time | N | String | Start time: Default : starting at this month format:YYYY-MM-DD HH:MM:SS (in Local Time) | 2016-08-01 11:00:00 |
end_time | N | String | End time: Default : end at this month format:YYYY-MM-DD HH:MM:SS (in Local Time) | 2016-08-21 11:00:00 |
page | N | Int | Number of pages: default:1 | 1 |
page_size | N | Int | Number of orders displayed on each page Default:10, max pagesize is 100 | 10 |
{'pay_type': '800201', 'page_size': 10, 'mchid': '9GGGDCRjYa', 'Page': 2} |
Parameters | Definition | Description | Example |
page | Int | Number of pages | 1 |
resperr | String | Information Description | |
page_size | Int | Number of orders displayed on each page | 10 |
String | Response code: 0000 stands for order placed successfully 1143,1145 stand for transaction on going, merchant need to continue querying transaction. if other codes returned, transaction failed | 0000 | |
data | List | Trade data type:list |
Description of parameter <data>:
Parameters | Definition | Description | Example |
syssn | String | Order number in QFPAY system | 201607280901020011216135 |
String No longer than 128 byte | Merchant's order number | 1470020842103 | |
pay_type | String | Payment type: wechat: 800201;alipay: 800101; | 800201 |
order_type | String | Order type: Payed order:payment; Refunded order:refund; Closed order:close; | payment |
txdtm | String | Transaction time: format:YYYY-MM-DD HH:MM:SS | 2016-08-01 11:07:22 |
txamt | Int | Amount of payment: It is measured in the minimum price unit of the transaction currency. | 10000 |
sysdtm | String | System time | 2016-07-28 11:01:39 |
cancel | Int | Cancel/refund: Normal trade:0 Cancel:2 refund:3 | 2 |
String | Response code: 0000 stands for order placed successfully 1143,1145 stand for transaction on going, merchant need to continue querying transaction. if other codes returned, transaction failed | ||
errmsg | String | Message of payment result |
The parameter respcd=0000 inside the data_list stands for the transaction is complete.
The respcd=0000 outside of the data_list stands for the order has been placed.
{'resperr': u'\u8bf7\u6c42\u6210\u529f', 'page_size': 1, 'respmsg': '', 'respcd': '0000', 'data': [{'pay_type': '800201', 'sysdtm': '2018-07-24 12:30:57', 'paydtm': '', 'txcurrcd': 'CNY', 'txdtm': '2018-07-24 13:31:03', 'txamt': '1', 'chnlsn': '', 'out_trade_no': '923500563158', 'syssn': '20180724000200020076586895', 'cancel': '0', 'respcd': '1143', 'errmsg': '\u8ba2 \u5355\u8fd8\u672a\u652f\u4ed8\uff0c\u6216\u8005\u6b63\u5728\u8f93\u5165\u5bc6\u 7801\u4e2d', 'order_type': 'payment'}], 'page': 1} |
1. What’s kind of order can be closed?
If the payment is unsuccessful, the order can always be canceled. If the cancel interface is called while the payment is successful made, which actually stands for calling the WeChat revoke API, and the payment for this order will be returned.
2. Scenarios of canceling the transaction
Cancel interface is only applicable at the time,which is mainly used to avoid double payments.
In order to avoid causing various unknown problems, please do not use the cancel interface as a refund interface.
Method | HTTP Post |
Path | /trade/v1/close |
Description | Close a transaction |
Parameter | Required | Definition | Description | Example |
mchid | Y | String | Merchant id: allocate by QFPAY(You can look up merchant ID in channel system) | BvDtmKJA5mx7GpN0 |
txamt | Y | Int | Amount of payment: It is measured in the minimum price unit of the transaction currency. | 10000 |
txdtm | Y | String | Transaction time : format: YYYY-MM-DD HH:MM:SS | 2016-08-01 11:07:22 |
syssn | N | String | Order number in QFPAY system. | 201607280901020011216137 |
N | String No longer than 128 byte | Merchant's order number | 1470020842103 | |
udid | N | String | UUID of device, no longer than 40 characters |
{'txdtm': '2018-07-24 15:20:09', 'syssn': '20180724000200020076667504', 'mchid': '9GGGDCRjYa', 'txamt': 1} |
Parameters | Definition | Description | Example |
syssn | String | Order number of the cancellation | 201607280901020011216137 |
orig_syssn | String | Original Order number of this transaction in QFPAY system | 201607280901020011216135 |
txamt | Int | Amount of payment: It is measured in the minimum price unit of the transaction currency. | 10000 |
txdtm | String | Request Transaction time : format: YYYY-MM-DD HH:MM:SS | 2016-07-26 17:02:01 |
sysdtm | String | System Transaction time | 2016-07-20 14:47:50 |
{"orig_syssn": "20180112000100020001659801", "sysdtm": "2018-01-12 19:07:02", "cardcd": "", "txdtm": "2018-01-12 19:07:09", "resperr": "\u4ea4\u6613\u6210\u529f", "txcurrcd": "CNY", "txamt": "1", "respmsg": "", "syssn": "20180112000100020001661611", "respcd": "0000"} |
Note: Cancel transaction is non-generic supported, there may be cases that do not support canceling the transaction. If the cancel interface response return code is "1297" or the returned content has no syssn field (note: not orig_syssn), the transaction does not support canceling the order. If the user Successfully paid, the refund interface can be called for a refund.
The merchant’s order number is custom generated by the merchant. It only supports the combination of alphanumeric characters, such as alphanumeric, underline _, vertical bar|, and asterisk *. Do not use special characters such as Chinese characters or full-width characters. The merchant order number is required to be unique (it is recommended to be generated based on the current system time plus a random sequence). To re-initiate a payment, use the original order number to avoid double payment; the order number that has been paid or has been called, and the cancelled order number cannot be reused for a new payment.
Notice: If not using, please not input this parameter to request parameters as the form of none.
no longer than 20 characters, special characters are not allowed. Note: special characters include full-width characters and symbols (★☆★$ & ¤ § | °゜ ¨ ± · × ÷ ˇ ˉ ˊ ˋ ˙ Γ Δ Θ Ξ Π Σ Υ Φ Ψ Ω α β γ δ ε ζ η θ ι κ λ μ ν ξ π ρ σ τ υ φ ψ ω Ё Б Г Д Е Ж З ИЙ К Л Ф У Ц Ч Ш Щ Ъ Ы Э Ю Я а б в г д ж з и й к л ф ц ч ш щ ъ ы ю я abcdefghijklmnopqrstuvwxyz - ― ‖ ‥ … ‰ ′ ″ ※ ℃ ℅ ℉ № ℡)
QFPay provides two environment for using our services:
Request Url: https://openapi-test.qfpay.com
1. During test, the money will not be operated. Please use little amount.
2. Mchid can be found in the channel system, which will be provided when formally applying the app-code and key.
3. Merchants under the same channel system can use the same app-code and key.
Request Url: https://openapi.qfpay.com
Please use your formal information including the mchid, code and key.
When there is no special statement, the signature in all request interfaces uses the format below:
How to make the interface parameter signature:
Step 1: Ascending order all parameters by parameter name。
Parameter list :abc=value1 bcd=value2 bad=value3
The ascending result:abc=value1 bad=value3 bcd=value2
Step 2:Connect all parameters with & to get the string to be signed.
abc=value1&bad=value3&bcd=value2
Step 3:Splice the string to be signed with the developer's Key.
abc=value1&bad=value3&bcd=value2Key
Step 4:Apply MD5 for the spliced string.
MD5(abc=value1&bad=value3&bcd=value2Key)
Step 5:Use signature to request the interface.
Store the signed results into the X-QF-SIGN in the HTTP head.
Python Sample:
When requesting API interface, parameters have to be set up as follows in the HTTP head.
Name | Required | Description |
X-QF-APPCODE | Y | The app_code assigned to the developer is the unique identifier of the developer. This parameter requires to be directly assigned from QFPay. |
X-QF-SIGN | Y | Signature generated according to the signature algorithm |
Description: after successfully requesting the interface, a JSON format buffer will be received and to be verified.
The response HTTP head is set up as follows’
{'Server': 'nginx', 'Date': 'Fri, 12 Jan 2018 11:31:18 GMT', 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': '302', 'Connection': 'keep-alive', 'X-QF-SIGN': '1E2CE7C2A7F8F581C354A857182B7A31', 'X-Powered-By': 'QF/1.1'} |
Parameters | Description |
When the respcd outside of data buffer is 0000, it stands for the order is successfully generated. | |
Resperr | Response information |
pay_type | Payment types |
MD5 data:{"pay_type": "800108", "sysdtm": "2018-01-12 19:31:16", "cardcd": "2088802362210279", "txdtm": "2018-01-12 19:31:22", "resperr": "\u4ea4\u6613\u6210\u529f", "txcurrcd": "CNY", "txamt": "1", "respmsg": "", "out_trade_no": "130145934788787530052", "syssn": "20180112000100020001662134", "respcd": "0000"}615ED178BA524459976CE40FAB78000F MD5 results:1E2CE7C2A7F8F581C354A857182B7A31 |
The notification callback address has to be provided to the technical support of QFPay through channel system. Each notification callback address can only be configured with one set of code and key, which can be modified.
If the order is successfully paid, the result of the notification callback will be returned. However, the notification callback may be delayed due to external factors. Therefore, please use query interface for the scene with real-time processing requirements. It is recommended that the notification callback can be used together with the query interface. For security reasons, notification callback only supports ports 80 and 443, and custom port assignments are not supported.
1. The address of the notification callback has to be provided to the technical support of QFPay by setting up in the channel system.
2. After the transaction succeeds, the QFPay will POST the notification data (JSON format) to the configured notification callback address.
3. After receiving the notification callback and verifying the signature, the developer needs to return the SUCCESS string to the QFPay, indicating that it has been processed.
4. If the developer returns other data to the QFPay, or if there is no return, then the QFpay will send the notification callback again with a certain strategy. The time interval is configured as 1m, 5m, 10m, 60m, 2h, 6h, 15h. Once the SUCCESS string is sent back to QFPay, the follow-up callback notices will not be continued.
Step 1: Get the signature from X-QF-SIGN in HTTP head.
Step 2: Connect the body of the HTTP response with Key to get the string to be verified.
Step 3: Apply MD5 for the spliced string. (SIGN = MD5(body + key))
Step 4: Compare the computing result with the signature from X-QF-SIGN to verify whether they are identical. If they are identical, the verification is successful and return SUCCESS string to QFPay.
import hashlib
unicode_to_utf8 = lambda s: s.encode('utf-8') if isinstance(s, unicode) else s
def make_resp_sign(data, key):
unsign_str = unicode_to_utf8(data) + unicode_to_utf8(key)
s = hashlib.md5(unsign_str).hexdigest()
return s.upper()
Parameter | Description |
notify_type | Notification types; payment; refund: close: |
syssn | Order number in QFPAY system |
String No longer than 128 byte | Merchant's order number: The merchant’s order number has to be unique. |
pay_type | Payment type: Wechat:800208;Alipay:800108; All-in-one swipe 800008; |
txdtm | Transaction time: format: YYYY-MM-DD HH:MM:SS |
txamt | Amount of payment: It is measured in the minimum price unit of the transaction currency. (Maximum 10,000 USD) |
Response code: 0000 stands for order placed successfully 1143,1145 stand for transaction in processing, merchant | |
sysdtm | System time |
paydtm | Time when the user made the payment. |
cancel | Marks for refunded or closed Processing:0;Closed:2;Refunded:3; |
cardcd | OpenID from Wechat or Alipay users |
Name of the product: special character is not allowed | |
status | Status of Transaction:1:The transaction is successful; |
txcurrcd | Currency code: JPY |
Merchant id: allocate by QFPAY(You can look up merchant ID in channel system) |
{"status": "1", "sysdtm": "2017-12-28 13:41:47", "paydtm": "2017-12-28 13:42:20", "goods_name": "", "txcurrcd": "CNY", "mchid": "XXxxxx", "cancel": "0", "pay_type": "800207", "cardcd": "oo3Lss1m9-eHSEyY2OGKzxFaRflY", "txdtm": "2017-12-28 13:41:47", "txamt": "200", "out_trade_no": "BO201712280117290001", "syssn": "20171228000300020044178249", "respcd": "0000", "goods_info": "", "notify_type": "payment"} |
#!/usr/bin/env python
#encoding=utf8
import urllib, urllib2, hashlib
import json
import argparse
import random
import qrcode
from datetime import datetime
from PIL import ImageFile
import hashlib
parser = argparse.ArgumentParser(description="Simulate Payment Process for QFPay and CIL")
parser.add_argument('--txamt', default=1, help='Payment Amount')
parser.add_argument('--type', default='wechat', help='Payment Type')
parser.add_argument('--cur', default='CNY', help='Payment Currency')
parser.add_argument('--authcode', help='Auth Code')
parser.add_argument('--syssn', help='Syssn Code')
parser.add_argument('--tradeno', help='Out Trade No')
parser.add_argument('--query', action='store_true', help='Perform Query')
parser.add_argument('--refund', action='store_true', help='Perform Refund')
parser.add_argument('--txdtm', help='Transaction Time')
parser.add_argument('--starttime', default=None)
parser.add_argument('--endtime', default=None)
parser.add_argument('--close', action='store_true')
parser.add_argument('--reconcile', action='store_true')
parser.add_argument('--tradedate', default=None)
unicode_to_utf8 = lambda s: s.encode('utf-8') if isinstance(s, unicode) else s
def make_req_sign(data, key):
keys = data.keys()
keys.sort()
p = []
for k in keys:
k = unicode_to_utf8(k)
v = unicode_to_utf8(data[k])
p.append('%s=%s'%(k,v))
unsign_str = '&'.join(p) + unicode_to_utf8(key)
s = hashlib.md5(unsign_str).hexdigest()
return s.upper()
def main():
pay_type = {
'wechat': '800201', #dynamic QR code generation
'alipay': '800101',
'wechat_app': '800208', #scan from user's app
'alipay_app': '800108', #scan from user's app
'general': '800008',
}
d = datetime.now()
# mchid = None
args = parser.parse_args()
txamt = args.txamt
txcurrcd = args.cur
pay_type = pay_type[args.type]
out_trade_no = random.randint(10**11, 10**12)
txdtm = d.strftime("%Y-%m-%d %H:%M:%S")
# goods_name = '商品名1:缶コーヒー'
goods_name = 'test'
limit_pay = 'no_credit'
auth_code = args.authcode
start_time = args.starttime
end_time = args.endtime
mchid = 'xxxxxxxxx'
app_code = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx'
key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx'
is_pay = True
url = 'https://openapi.qfpay.com/trade/v1/payment'
data ={'txamt': txamt, 'txcurrcd': txcurrcd, 'pay_type': pay_type, 'out_trade_no': out_trade_no, 'txdtm': txdtm, 'goods_name':goods_name,'limit_pay':limit_pay,'udid':udid}
if mchid: data['mchid'] = mchid
if args.type in ['wechat_app', 'alipay_app', 'general']:
data['auth_code'] = auth_code
if args.query:
is_pay = False
url = 'https://openapi.qfpay.com/trade/v1/query'
data = { 'pay_type': pay_type, 'mchid': mchid, 'page_size': 1, 'Page': 2}
if start_time: data['start_time'] = start_time
if end_time: data['end_time'] = end_time
elif args.refund:
is_pay = False
url = 'https://openapi.qfpay.com/trade/v1/refund'
data = { 'syssn': args.syssn, 'out_trade_no': args.tradeno, 'pay_type': pay_type,'mchid': mchid, 'txamt': txamt, 'txdtm': args.txdtm}
elif args.close:
is_pay = False
url = 'https://openapi.qfpay.com/trade/v1/close'
data = {'txamt': txamt, 'txdtm': args.txdtm, 'mchid': mchid }
if args.syssn is not None: data['syssn'] = syssn
if args.tradeno is not None: data['out_trade_no'] = args.tradeno
elif args.reconcile:
url = 'https://openapi.qfpay.com/download/v1/trade_bill'
data = { 'trade_date': args.tradedate }
print(data)
req = urllib2.Request(url, urllib.urlencode(data))
req.add_header('X-QF-APPCODE', app_code)
req.add_header('X-QF-SIGN', make_req_sign(data, key))
resp = urllib2.urlopen(req)
output = json.loads(resp.read())
print resp.info()
print output
print output['respcd']
print output['resperr'].encode("utf-8")
if output['respcd'] == '0000' and args.type in ['wechat', 'alipay'] and is_pay:
img = qrcode.make(output['qrcode'])
img.save('qrcode.png')
if __name__ == '__main__':
main()