Installation
# installation
pip install python-alipay-sdk --upgrade
# For python2, use: pip install python-alipay-sdk==1.1
Cert generation
# 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
The public key we download from open.alipay.com is a string, which cannot be recognied by this lib directly, making sure it's surrounded with
-----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY-----
There is also an example for your reference
Initialization
from alipay import AliPay, DCAlipay, ISVAliPay # Making sure your key file is adhered to standards. # you may find examples at tests/certs/ali/ali_private_key.pem app_private_key_string = open("/path/to/your/private/key.pem").read() alipay_public_key_string = open("/path/to/alipay/public/key.pem").read() app_private_key_string = """ -----BEGIN RSA PRIVATE KEY----- base64 encoded content -----END RSA PRIVATE KEY----- """ alipay_public_key_string = """ -----BEGIN PUBLIC KEY----- base64 encoded content -----END PUBLIC KEY----- """ alipay = AliPay( appid="", app_notify_url=None, # the default notify path app_private_key_string=app_private_key_string, # alipay public key, do not use your own public key! alipay_public_key_string=alipay_public_key_string, sign_type="RSA", # RSA or RSA2 debug=False # False by default ) dc_alipay = DCAliPay( appid="appid", app_notify_url="http://example.com/app_notify_url", app_private_key_string=app_private_key_string, app_public_key_cert_string=app_public_key_cert_string, alipay_public_key_cert_string=alipay_public_key_cert_string, alipay_root_cert_string=alipay_root_cert_string ) # Forget about what I mentioned below if you don't know what ISV is # either app_auth_code or app_auth_token should not be None isv_alipay = ISVAliPay( appid="", app_notify_url=None, # the default notify path app_private_key_string="", # alipay public key, do not use your own public key! alipay_public_key_string=alipay_public_key_string, sign_type="RSA" # RSA or RSA2 debug=False # False by default, app_auth_code=None, app_auth_token=None )
DCAlipay is a must for certain Alipay APIs
Naming convention
Given an alipay function, say alipay.trade.page.pay
, we will defind a corresponding function alipay.api_alipay_trade_page_pay()
Generally we will do such a translation:
function_name = "api_" + alipay_function_name.replace(".", "_")
According to alipay document, some paremeters in biz_content
are optional and some are not. We defind functions in this way so that you can put those optional parameters into kwargs
:
def api_alipay_xxx(self, out_trade, total_amount, **kwargs):
...
biz_content.update(kwargs)
# For Python 2 users(you should really think about Python 3), # making sure non-ascii strings are utf-8 encoded subject = u"测试订单".encode("utf8") # For Python 3 users, just use the default string subject = "测试订单" # Pay via Web,open this url in your browser: https://openapi.alipay.com/gateway.do? + order_string order_string = alipay.api_alipay_trade_page_pay ( out_trade_no="20161112", total_amount=0.01, subject=subject, return_url="https://example.com", notify_url="https://example.com/notify" # this is optional )
# Pay via WAP, open this url in your browser: https://openapi.alipay.com/gateway.do? + order_string order_string = alipay.api_alipay_trade_wap_pay( out_trade_no="20161112", total_amount=0.01, subject=subject, return_url="http://example.com", notify_url="https://example.com/notify" # this is optional )
# Pay via App,just pass order_string to your Android or iOS client order_string = alipay.api_alipay_trade_app_pay( out_trade_no="20161112", total_amount=0.01, subject=subject, notify_url="https://example.com/notify" # this is optional )
Once an order is paid, a POST request will be sent to tell you the information
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() # sign must be poped out signature = data.pop("sign") print(json.dumps(data)) print(signature) # verify success = alipay.verify(data, signature) if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED" ): print("trade succeed") return 'Hello, World!'
And also an example for Django
def hello_world(request): # for django users data = request.dict() # for rest_framework users data = request.data signature = data.pop("sign") # verification success = alipay.verify(data, signature) if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED" ): print("trade succeed") return 'Hello, World!'
Here is a more general example for verification
# gathering all parameters sent from alipay server, and put them into 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") success = alipay.verify(data, signature) if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED" ): print("trade succeed")
alipay = AliPay(appid="", ...) result = alipay.api_alipay_trade_pay( out_trade_no="out_trade_no", scene="bar_code/wave_code", auth_code="auth_code", subject="subject", discountable_amount=10, total_amount=20, notify_url="https://example.com/notify" # this is optional ) if result["code"] == "10000": print("Order is paid")
alipay.trade.precreate/alipay.trade.cancel/alipay.trade.query
alipay = AliPay(appid="", ...) # create an order alipay.api_alipay_trade_precreate ( subject="test subject", out_trade_no="out_trade_no", total_amount=100 ) # 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.api_alipay_trade_query(out_trade_no="out_trade_no") 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.api_alipay_trade_cancel(out_trade_no=out_trade_no)
If you want to know what parameters are accepted, take a look into the official document
result = alipay.api_alipay_trade_refund(out_trade_no="xxx", refund_amount="xxx", ...) if result["code"] == "10000": print("success")
alipay.trade.fastpay.refund.query
result = alipay.api_alipay_trade_fastpay_refund_query("20171120", out_trade_no="20171120") result = { 'code': '10000', 'msg': 'Success', 'out_request_no': '20171120', 'out_trade_no': '20171120', 'refund_amount': '20.00', 'total_amount': '20.00', 'trade_no': '2017112021001004070200297107' }
result = alipay.api_alipay_trade_order_settle( out_request_no, trade_no, royalty_parameters )
result = alipay.api_alipay_trade_close( trace_no="xxx", out_trade_no="xxx", operator_id="this is optional" ) result = { "code": "10000", "msg": "Success", "trade_no": "2013112111001004500000675971", "out_trade_no": "YX_001" }
alipay.fund.trans.toaccount.transfer
# transfer money to alipay account result = alipay.api_alipay_fund_trans_toaccount_transfer( datetime.now().strftime("%Y%m%d%H%M%S"), payee_type="ALIPAY_LOGONID/ALIPAY_USERID", payee_account="csqnji8117@sandbox.com", amount=3.12 ) result = { 'code': '10000', 'msg': 'Success', 'order_id': '', 'out_biz_no': '', 'pay_date': '2017-06-26 14:36:25' }
result = alipay.api_alipay_fund_trans_order_query( out_biz_no="20170626152216" ) print(result)
Go through the details before you do anything, or it may pains.
alipay.open.auth.token.app
isv_alipay = ISVAliPay(
...
app_auth_code="app_auth_code"
)
response = isv_alipay.api_alipay_open_auth_token_app()
response = {
"code": "10000",
"msg": "Success",
"app_auth_token": "201708xxx",
"app_refresh_token": "201708xxx",
"auth_app_id": "appid",
"expires_in": 31536000,
"re_expires_in": 32140800,
"user_id": "2088xxxxx
}
alipay.open.auth.token.app.query
response = isv_alipay.alipay_open_auth_token_app_query()
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)