Django调用支付宝接口代码实例详解
支付宝支付
正式环境:用营业执照,申请商户号,appid
测试环境:沙箱环境:https://openhome.alipay.com/platform/appDaily.htm?tab=info
支付宝提供接口:给商户使用,收钱
- -Java,php,C#的demo,没有python的demo
- -git有人封装了
- -需要安装模块:pip3install
- -应用私钥---自己保存,一定不能丢
- -应用公钥---给别人用
- -支付宝公钥---支付宝用的
- -生成公钥私钥:https://docs.open.alipay.com/291/105971
- -把应用公钥配置在支付宝上:应用公钥,配置完成以后,支付宝自动生成一个支付宝公钥
- -在程序中:配置应用私钥,支付宝公钥
- -如果支付成功,支付宝会回调,但是如果你的服务器挂掉了怎么办?
- -支付宝24小时以内不定时再给你发,你修改掉订单状态即可
- -支付成功,支付宝会有一个get回调,一个post回调:修改订单状态
支付宝接口
fromdatetimeimportdatetime
fromCrypto.PublicKeyimportRSA
fromCrypto.SignatureimportPKCS1_v1_5
fromCrypto.HashimportSHA256
fromurllib.parseimportquote_plus
frombase64importdecodebytes,encodebytes
importjson
classAliPay(object):
"""
支付宝支付接口(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_path=app_private_key_path
self.app_private_key=None
self.return_url=return_url
withopen(self.app_private_key_path)asfp:
self.app_private_key=RSA.importKey(fp.read())
self.alipay_public_key_path=alipay_public_key_path
withopen(self.alipay_public_key_path)asfp:
self.alipay_public_key=RSA.importKey(fp.read())
ifdebugisTrue:
self.__gateway="https://openapi.alipaydev.com/gateway.do"
else:
self.__gateway="https://openapi.alipay.com/gateway.do"
defdirect_pay(self,subject,out_trade_no,total_amount,return_url=None,**kwargs):
biz_content={
"subject":subject,
"out_trade_no":out_trade_no,
"total_amount":total_amount,
"product_code":"FAST_INSTANT_TRADE_PAY",
#"qr_pay_mode":4
}
biz_content.update(kwargs)
data=self.build_body("alipay.trade.page.pay",biz_content,self.return_url)
returnself.sign_data(data)
defbuild_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
}
ifreturn_urlisnotNone:
data["notify_url"]=self.app_notify_url
data["return_url"]=self.return_url
returndata
defsign_data(self,data):
data.pop("sign",None)
#排序后的字符串
unsigned_items=self.ordered_data(data)
unsigned_string="&".join("{0}={1}".format(k,v)fork,vinunsigned_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))fork,vinunsigned_items)
#获得最终的订单信息字符串
signed_string=quoted_string+"&sign="+quote_plus(sign)
returnsigned_string
defordered_data(self,data):
complex_keys=[]
forkey,valueindata.items():
ifisinstance(value,dict):
complex_keys.append(key)
#将字典类型的数据dump出来
forkeyincomplex_keys:
data[key]=json.dumps(data[key],separators=(',',':'))
returnsorted([(k,v)fork,vindata.items()])
defsign(self,unsigned_string):
#开始计算签名
key=self.app_private_key
signer=PKCS1_v1_5.new(key)
signature=signer.sign(SHA256.new(unsigned_string))
#base64编码,转换为unicode表示并移除回车
sign=encodebytes(signature).decode("utf8").replace("\n","")
returnsign
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"))
ifsigner.verify(digest,decodebytes(signature.encode("utf8"))):
returnTrue
returnFalse
defverify(self,data,signature):
if"sign_type"indata:
sign_type=data.pop("sign_type")
#排序后的字符串
unsigned_items=self.ordered_data(data)
message="&".join(u"{}={}".format(k,v)fork,vinunsigned_items)
returnself._verify(message,signature)
视图函数
fromdjango.shortcutsimportrender,redirect,HttpResponse
fromutils.payimportAliPay
importjson
importtime
defali():
#沙箱环境地址:https://openhome.alipay.com/platform/appDaily.htm?tab=info
app_id="2016092000554611"
#支付宝收到用户的支付,会向商户发两个请求,一个get请求,一个post请求
#POST请求,用于最后的检测
notify_url="http://42.56.89.12:80/page2/"
#GET请求,用于页面的跳转展示
return_url="http://42.56.89.12:80/page2/"
merchant_private_key_path="keys/app_private_2048.txt"
alipay_public_key_path="keys/alipay_public_2048.txt"
#生成一个AliPay的对象
alipay=AliPay(
appid=app_id,
app_notify_url=notify_url,
return_url=return_url,
app_private_key_path=merchant_private_key_path,
alipay_public_key_path=alipay_public_key_path,#支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥
debug=True,#默认False,
)
returnalipay
defpage1(request):
ifrequest.method=="GET":
returnrender(request,'page1.html')
else:
money=float(request.POST.get('money'))
#生成一个对象
alipay=ali()
#生成支付的url
#对象调用direct_pay
query_params=alipay.direct_pay(
subject="充气娃娃",#商品简单描述
out_trade_no="x2"+str(time.time()),#商户订单号
total_amount=money,#交易金额(单位:元保留俩位小数)
)
pay_url="https://openapi.alipaydev.com/gateway.do?{}".format(query_params)
print(pay_url)
#朝这个地址发get请求
returnredirect(pay_url)
defpage2(request):
alipay=ali()
ifrequest.method=="POST":
#检测是否支付成功
#去请求体中获取所有返回的数据:状态/订单号
fromurllib.parseimportparse_qs
body_str=request.body.decode('utf-8')
print(body_str)
post_data=parse_qs(body_str)
print('支付宝给我的数据:::---------',post_data)
post_dict={}
fork,vinpost_data.items():
post_dict[k]=v[0]
print('转完之后的字典',post_dict)
sign=post_dict.pop('sign',None)
status=alipay.verify(post_dict,sign)
print('POST验证',status)
returnHttpResponse('POST返回')
else:
params=request.GET.dict()
sign=params.pop('sign',None)
status=alipay.verify(params,sign)
print('GET验证',status)
returnHttpResponse('支付成功')
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。