- 需要配置沙箱环境
- 设置异步回调地址
- 更多信息转载自: https://www.cnblogs.com/liuwei0824/p/8493838.html
views视图处理
def AliPay(request): if request.is_secure(): notify_url = "https://%s/xxx/xxx/" % request.get_host() # 异步通知 return_url = "https://%s/xxx/xxx/" % request.get_host() # 同步通知 else: notify_url = "http://%s/xxx/xxx/" % request.get_host() return_url = "http://%s/xxx/xxx/" % request.get_host() # 沙箱环境地址 alipay = AliPay( appid="", app_notify_url=notify_url, return_url=return_url, app_private_key_path="", alipay_public_key_path="", # 打开文件模式 """ app_private_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/app_private_key.pem"), alipay_public_key_path=os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys/alipay_public_key.pem"), # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥, """ ) data = request.GET money_key = data.get('money_key') total_key = data.get('total_key') query_params = alipay.direct_pay( subject=WEBSITE_CONF[request.get_host()]["website_name"], # 名 out_trade_no=total_key, # 商户订单号 total_amount=money_key, # 交易金额 return_url=return_url, ) alipay_url = "https://openapi.alipay.com/gateway.do?{0}".format(query_params) response = HttpResponse(json.dumps({"alipay_url": alipay_url})) return response
支付宝工具Utils
class AliPay(): """支付宝支付接口(PC端支付接口)""" # 初始化信息 def __init__(self, appid, app_notify_url, app_private_key_path, alipay_public_key_path, return_url, debug=False): self.appid = appid # 开发者的应用 self.app_notify_url = app_notify_url self.app_private_key = RSA.importKey(app_private_key_path) # 公钥 self.alipay_public_key = RSA.importKey(alipay_public_key_path) self.return_url = return_url # 返回的url # 使用文件读取模式打开下面 """ self.app_private_key_path = app_private_key_path self.alipay_public_key_path = app_private_key_path with open(self.app_private_key_path) as fp: self.app_private_key = RSA.importKey(fp.read()) with open(self.alipay_public_key_path) as fp: self.alipay_public_key = RSA.importKey(fp.read()) """ if debug is True: self.__gateway = "https://openapi.alipaydev.com/gateway.do" else: self.__gateway = "https://openapi.alipay.com/gateway.do" def direct_pay(self, subject, out_trade_no, total_amount, return_url, **kwargs): biz_content = { "subject": subject, # 订单标题 "out_trade_no": out_trade_no, # 商户订单号 "total_amount": total_amount, # 订单金额 "product_code": "FAST_INSTANT_TRADE_PAY", # 快速即时贸易支付 'return_url': return_url # "qr_pay_mode":4 } biz_content.update(kwargs) data = self.build_body("alipay.trade.page.pay", biz_content, self.return_url) return self.sign_data(data) def build_body(self, method, biz_content, return_url=None): data = { "app_id": self.appid, "method": method, "charset": "utf-8", "sign_type": "RSA2", "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "version": "1.0", "biz_content": biz_content } if return_url is not None: data["notify_url"] = self.app_notify_url data["return_url"] = self.return_url return data def sign_data(self, data): data.pop("sign", None) # 排序后的字符串 unsigned_items = self.ordered_data(data) unsigned_string = "&".join("{0}={1}".format(k, v) for k, v in unsigned_items) sign = self.sign(unsigned_string.encode("utf-8")) # ordered_items = self.ordered_data(data) quoted_string = "&".join("{0}={1}".format(k, quote_plus(v)) for k, v in unsigned_items) # 获得最终的订单信息字符串 signed_string = quoted_string + "&sign=" + quote_plus(sign) return signed_string def ordered_data(self, data): complex_keys = [] for key, value in data.items(): if isinstance(value, dict): complex_keys.append(key) # 将字典类型的数据dump出来 for key in complex_keys: data[key] = json.dumps(data[key], separators=(',', ':')) return sorted([(k, v) for k, v in data.items()]) def sign(self, unsigned_string): # 开始计算签名 key = self.app_private_key signer = PKCS1_v1_5.new(key) signature = signer.sign(SHA256.new(unsigned_string)) # base64 编码,转换为unicode表示并移除回车 sign = b64encode(signature).decode("utf8").replace("\n", "") return sign def _verify(self, raw_content, signature): # 开始计算签名 key = self.alipay_public_key signer = PKCS1_v1_5.new(key) digest = SHA256.new() digest.update(raw_content.encode("utf8")) if signer.verify(digest, b64decode(signature.encode("utf8"))): return True return False def verify(self, data, signature): if "sign_type" in data: sign_type = data.pop("sign_type") # 排序后的字符串 unsigned_items = self.ordered_data(data) message = "&".join(u"{}={}".format(k, v) for k, v in unsigned_items) return self._verify(message, signature)