轉載請注明原文地址:http://www.cnblogs.com/ygj0930/p/7680348.html
一:配置信息准備
登錄螞蟻金服開放平台:https://open.alipay.com/platform/home.htm
開發資料閱讀:https://docs.open.alipay.com/194/106078
創建好應用,配置好密鑰等信息后,就可以開發了。
二:開發支付寶支付工具類
1:相關配置信息
# ========支付相關配置信息=========== ALIPAY_INPUT_CHARSET = 'utf-8' # 商戶ID,以2088開頭的16位純數字 ALIPAY_PARTNER = '2088************' # 服務商支付寶賬號 ALIPAY_SELLER_EMAIL = '' # 支付結果回調地址 ALIPAY_NOTIFY_URL = "商家后台回調接口地址" # 訪問模式,根據自己的服務器是否支持ssl訪問,若支持請選擇https;若不支持請選擇http ALIPAY_TRANSPORT = 'https' #簽名加密方式 SIGN_TYPE = "SHA-1" #應用id APP_ID = '************' #下單api precreate_GATEWAY="https://openapi.alipay.com/gateway.do?"
2:三個輔助函數:
#1:生成下單請求參數字符串 def make_payment_request(self,params_dict): """ 構造支付請求參數 :param params_dict: :return: """ query_str = self.params_to_query(params_dict,) # 拼接參數字符串 sign = self.make_sign(query_str) # 生成簽名 sign = urllib.quote(sign, safe='') #解決中文參數編碼問題 res = "%s&sign=%s" % (query_str, sign) return res def params_to_query(self,params): """ 生成需要簽名的字符串 :param params: :return: """ """ :param params: :return: """ query = "" dict_items = {} for key, value in params.items(): if isinstance(value, dict) == True: dict_items[key] = value params[key] = "%s" all_str = '' for key in sorted(params.keys()): #把參數按key值排序:這是支付寶下單請求的參數格式規定 all_str = all_str + '%s=%s&' % (key, params[key]) all_str = all_str.rstrip('&') biz_content_dict = dict_items['biz_content'] content_str = '' for key in sorted(biz_content_dict.keys()): if isinstance(biz_content_dict[key], basestring) == True: content_str = content_str + '"%s":"%s",' % (key, biz_content_dict[key]) else: content_str = content_str + '"%s":%s,' % (key, biz_content_dict[key]) content_str = content_str.rstrip(',') content_str = '{' + content_str + '}' query = all_str % content_str return query def make_sign(self,para_str): """ 生成簽名 :param message: :return: """ private_key = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, open( './路徑/private_key.txt').read()) #把私鑰存到一個文件里,加載出來【嘗試過用rsa模塊的方法加載私鑰字符串,會報格式錯誤。查看源碼得知,需要從文件流加載】 import sys reload(sys) sys.setdefaultencoding('utf-8') #這三句:解決簽名方法編碼報錯 sign = base64.encodestring(OpenSSL.crypto.sign(private_key, para_str, 'sha256')) return sign
3:下單
#獲取二維碼url def getAlipayUrl(self,orderid,goodsName,goodsPrice,**kwargs): # 構建公共參數 params = {} params['method'] = 'alipay.trade.precreate' params['version'] = '1.0' params['app_id'] = self.APP_ID params['timestamp'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') params['charset'] = self.ALIPAY_INPUT_CHARSET params['notify_url'] = self.ALIPAY_NOTIFY_URL params['sign_type'] = 'RSA2' # 構建訂單參數 biz_content = {} biz_content['out_trade_no'] = orderid # 訂單號 biz_content['subject'] = goodsName #商品名 biz_content['total_amount'] = goodsPrice # 價格 params['biz_content'] = biz_content #由參數,生成簽名,並且拼接得到下單參數字符串 encode_params = self.make_payment_request(params) #下單 url = self.precreate_GATEWAY + encode_params response = requests.get(url) #提取下單響應 body = response.text #解析下單響應json字符串 body_dict = json.loads(body) return_msg = body_dict['alipay_trade_precreate_response']['msg'] if return_msg == "Success": code_url = body_dict['alipay_trade_precreate_response']['qr_code'] return code_url else: print "fail msg=============" + return_msg
三:在controller端,接收客戶端傳過來的訂單號、商品名、商品價格,調用支付工具類,得到二維碼鏈接,根據鏈接生成二維碼,傳給客戶端
(此處同微信掃碼支付模式二)
四:在controller端,編寫支付結果回調函數
def aliQRCodeNotify(self, request, *args,**kwargs): out_trade_no = kwargs.get("out_trade_no") trade_status = kwargs.get("trade_status") #根據trade_status,判斷交易結果:交易成功 or 交易關閉 #根據out_trade_no 更新訂單記錄信息
五:客戶端輪詢
同微信掃碼支付模式二客戶端輪詢思路。