I can't find any official python alipay sdks so far, and it really pains a lot dealing with those sign methods. Hoping this libarary could do some help :).
So far, the following functions are supported:
- Paid via Android/iOS
- Paid via WAP
- Paid via Web
- Refund
- Create face to face trade
- Query face to face trade
- Cancel face to face trade
- Precreate face to face trade
Taking a look at this guide if you are interested at the details on signing your order requests. Or you may just follow this manual if you are not.
pip install python-alipay-sdk
openssl
OpenSSL> genrsa -out app_private_key.pem 2048 # the private key file
OpenSSL> rsa -in app_private_key.pem -pubout -out app_public_key.pem # export public key
OpenSSL> exit
from alipay import AliPay
# paid via WAP or iOS/Android
alipay = AliPay(
appid="",
app_notify_url="",
app_private_key_path="",
app_alipay_public_key_path="", # public key which belongs to alipay, this is used to validate messages sent from alipay server.
sign_type="RSA" # RSA or RSA2
)
# paid via Web
alipay = AliPay(
partner="",
web_notify_url="",
web_private_key_path="",
web_alipay_public_key_path="" # public key which belongs to alipay, this is used to validate messages sent from alipay server.
)
# Intialize alipay in this way if you want to handling all the paying methods mentioned,
alipay = AliPay(
appid="",
app_notify_url="",
app_private_key_path="",
app_alipay_public_key_path="",
partner="",
web_notify_url="",
web_private_key_path="",
web_alipay_public_key_path=""
)
# if you are using Python 2(you should really think about Python 3), making sure non-ascii strings are utf-8 encoded
subject = u"测试订单".encode("utf8")
# if you are Python3 user, just use the default string
subject = "测试订单"
# paid via App,just generating order_string and pass it to your mobile app
order_string = alipay.create_app_trade(out_trade_no="20161112", total_amount=0.01, subject="testing order")
# paid via WAP, open this url in your browser: https://openapi.alipay.com/gateway.do? + order_string
order_string = alipay.create_wap_trade(out_trade_no="20161112", total_amount=0.01, subject="testing order", return_url="https://example.com")
# paid via Web,open this url in your browser: https://mapi.alipay.com/gateway.do? + order_string
order_string = alipay.create_web_trade(out_trade_no="20161112", total_amount=0.01, subject="testing order", return_url="https://example.com")
Once an order is paid, you will get a POST request from alipay servers which informs you that the order is paid
Here is a simple example for flask web server:
import json
from flask import Flask
from flask import request
app = Flask(__name__)
@app.route('/', methods=["GET", "POST"])
def hello_world():
data = request.form.to_dict()
signature = data.pop("sign")
print(json.dumps(data))
print(signature)
# verify
alipay.verify_wap/web/app_notify(data, signature)
return 'Hello, World!'
Here is a more general example for verification
# gathering all parameters sent from alipay server, and put them in a dictionary called data
data = {
"subject": "testing order",
"gmt_payment": "2016-11-16 11:42:19",
"charset": "utf-8",
"seller_id": "xxxx",
"trade_status": "TRADE_SUCCESS",
"buyer_id": "xxxx",
"auth_app_id": "xxxx",
"buyer_pay_amount": "0.01",
"version": "1.0",
"gmt_create": "2016-11-16 11:42:18",
"trade_no": "xxxx",
"fund_bill_list": "[{\"amount\":\"0.01\",\"fundChannel\":\"ALIPAYACCOUNT\"}]",
"app_id": "xxxx",
"notify_time": "2016-11-16 11:42:19",
"point_amount": "0.00",
"total_amount": "0.01",
"notify_type": "trade_status_sync",
"out_trade_no": "xxxx",
"buyer_logon_id": "xxxx",
"notify_id": "xxxx",
"seller_email": "xxxx",
"receipt_amount": "0.01",
"invoice_amount": "0.01",
"sign": "xxx"
}
signature = data.pop("sign")
# Verification for App
success = alipay.verify_app_notify(data, signature)
# Verification for WAP
success = alipay.verify_wap_notify(data, signature)
# Verification for Web
success = alipay.verify_web_notify(data, signature)
if success and (data["trade_status"] == "TRADE_SUCCESS" or data["trade_status"] == "TRADE_FINISHED" ):
print("trade succeed")
If you want to know what parameters are accepted, take a look into the official document, they are listed in 请求参数
# Example for refund
result = alipay.refund_web_order(out_trade_no="xxx", refund_amount="xxx", ...)
result = alipay.refund_app_order(out_trade_no="xxx", refund_amount="xxx", ...)
result = alipay.refund_wap_order(out_trade_no="xxx", refund_amount="xxx", ...)
if result["code"] == "10000":
print("success")
alipay = AliPay(appid="", ...)
result = alipay.create_face_to_face_trade(
"out_trade_no", "bar_code/wave_code", "auth_code", "subject",
discountable_amount=10,
total_amount=20,
# you may input more parameters here, refer to alipay official doc for details
)
if result["code"] == "10000":
print("Order is paid")
alipay = AliPay(appid="", ...)
# create an order
result1 = alipay.precreate_face_to_face_trade(
"out_trade_no", 100, "test subject"
# you may input more parameters here, refer to alipay official doc for details
)
# check order status
paid = False
for i in range(10):
# check every 3s, and 10 times in all
print("now sleep 3s")
time.sleep(3)
result = alipay.query_face_to_face_trade(out_trade_no="out_trade_no24")
if result.get("trade_status", "") == "TRADE_SUCCESS":
paid = True
break
print("not paid...")
# order is not paid in 30s , cancel this order
if paid is False:
alipay.cancel_face_to_face_trade(out_trade_no=out_trade_no)
python -m unittest discover
Or you may do test manually in this way, debug=True
will direct your request to sandbox environment:
alipay = AliPay(..., debug=True)
- varwey
- bug fix for encocode issue in verify data
- bug fix for ascii encode error in python2
- bug fix for create wap trade
- validation for sync response
- several bug fix
- precreate/create/cancel/query face to face trade
- return response body instead of raising exception even if code is not 10000
- Refund bug fix( many thanks to varwey)
- SHA256withRSA is the default sign method now, if you want to use SHA1withRSA,set
sign_type = "RSA"
while intializing alipay instance
- Refund functions
- Code for testing
- Fixed coding and decoding issues in Python 2