这里使用的是支付宝的沙箱环境:https://open.alipay.com/platform/appDaily.htm 。
关于沙箱的具体配置请看 https://opendocs.alipay.com/common/02kkv7 。
我们直接来说 python 如何使用支付宝 API。
安装依赖 1 pip install alipay-sdk-pytho
使用 实例化客户端 发起支付、查询交易信息、退款等服务都需要实例化一个客户端。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from alipay.aop.api.DefaultAlipayClient import DefaultAlipayClientfrom alipay.aop.api.AlipayClientConfig import AlipayClientConfigalipay_client_config = AlipayClientConfig() alipay_client_config.server_url = current_app.config['SERVER_URL' ] alipay_client_config.app_id = current_app.config['APP_ID' ] alipay_client_config.app_private_key = current_app.config['APP_PRIVATE_KEY' ] alipay_client_config.alipay_public_key = current_app.config['ALIPAY_PUBLIC_KEY' ] client = DefaultAlipayClient(alipay_client_config)
构造请求参数模型 不同的服务需要构造不同的参数模型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 '''发起支付''' from alipay.aop.api.domain.AlipayTradePagePayModel import AlipayTradePagePayModelmodel = AlipayTradePagePayModel() model.out_trade_no = order_id model.total_amount = price model.subject = name model.timeout_express = '5m' model.product_code = 'FAST_INSTANT_TRADE_PAY' '''交易查询''' from alipay.aop.api.domain.AlipayTradeQueryModel import AlipayTradeQueryModelmodel = AlipayTradeQueryModel() model.out_trade_no = '202112221533' '''退款''' from alipay.aop.api.domain.AlipayTradeRefundModel import AlipayTradeRefundModelmodel = AlipayTradeRefundModel() model.out_trade_no = '202112221533' model.refund_amount = 100.50
当然,我们也可以不使用模型来传参,直接向对应请求对象中的 biz_content
赋值,例如退款:
1 2 3 4 from alipay.aop.api.request.AlipayTradeRefundRequest import AlipayTradeRefundRequestrefund_request = AlipayTradeRefundRequest() refund_request.biz_content = {'out_trade_no' : trade_no, 'refund_amount' : price}
发起请求并处理响应 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 '''发起支付''' from alipay.aop.api.request.AlipayTradePagePayRequest import AlipayTradePagePayRequestpay_request = AlipayTradePagePayRequest(biz_model=model) pay_request.notify_url = 'http://192.168.31.196:5000/pay_result' pay_request.return_url = 'http://192.168.31.196:5000/order' pay_url = client.page_execute(pay_request, http_method='GET' ) return jsonify({'url' : pay_url})'''查询交易''' from alipay.aop.api.request.AlipayTradeQueryRequest import AlipayTradeQueryRequestfrom alipay.aop.api.response.AlipayTradeQueryResponse import AlipayTradeQueryResponsequery_request = AlipayTradeQueryRequest(biz_model=model) try : response_content = client.execute(query_request) except Exception as e: print (e) response = AlipayTradeQueryResponse() response.parse_response_content(response) if res.is_success(): print (response.out_trade_no) else : ... '''退款''' from alipay.aop.api.request.AlipayTradeRefundRequest import AlipayTradeRefundRequestfrom alipay.aop.api.response.AlipayTradeRefundResponse import AlipayTradeRefundResponse
在支付请求中,当用户支付完成后支付宝会向 notify_url
中的地址发送 post 请求,将订单的信息返回,但必须要求这个地址能够被外网访问,否则不会被请求。
我们得到返回的结果后,需要进行验签:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from alipay.aop.api.util.SignatureUtils import verify_with_rsadef checkSign (params ): sign = params.pop('sign' ) params.pop('sign_type' ) params_sorted = sorted (params.items(), key=lambda x:x[0 ], reverse=False ) params_encode = '&' .join('{}={}' .format (k, v) for k,v in params_sorted).encode() return verify_with_rsa(current_app.config['ALIPAY_PUBLIC_KEY' ], params_encode, sign) params = request.form if checkSign(params): ...