最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python采用django框架實(shí)現(xiàn)支付寶即時(shí)到帳接口

 更新時(shí)間:2016年05月17日 14:12:10   作者:hornbills  
這篇文章主要介紹了python采用django框架實(shí)現(xiàn)支付寶即時(shí)到帳接口的相關(guān)資料,需要的朋友可以參考下

因工作需要研究了支付寶即時(shí)到帳接口,并成功應(yīng)用到網(wǎng)站上,把過程拿出來分享。

即時(shí)到帳只是支付寶眾多商家服務(wù)中的一個(gè),表示客戶付款,客戶用支付寶付款,支付寶收到款項(xiàng)后,馬上通知你,并且此筆款項(xiàng)與交易脫離關(guān)系,商家可以馬上使用。

即時(shí)到帳只對(duì)企業(yè)客戶服務(wù),注冊(cè)成功企業(yè)賬號(hào)以后,申請(qǐng)簽約即時(shí)到帳產(chǎn)品,大約3-5個(gè)工作日后,簽約成功,可以馬上進(jìn)入集成產(chǎn)品階段。

這個(gè)是支付寶提供的接口,有asp,c#,java,php四種語言的,每種語言提供GBK和UTF-8兩種方案。另帶一份支付寶的文檔,這份文檔我感覺本來簡(jiǎn)單的事情越說越麻煩了。

網(wǎng)上搜了一下,發(fā)現(xiàn)Python接口有幾個(gè)現(xiàn)成的方案。
https://github.com/fengli/alipay_python

這兩個(gè)是一個(gè),代碼我還沒看,寫文檔的時(shí)候發(fā)現(xiàn)的。
https://github.com/lxneng/alipay
https://pypi.python.org/pypi/alipay/0.2.2

支付寶即時(shí)到帳交易過程。

商家:是指支付寶的企業(yè)客戶。也就是你集成服務(wù)單位。
終端消費(fèi)者:是指在網(wǎng)上購物的消費(fèi)者,你集成服務(wù)單位的客戶。

1、終端消費(fèi)者在商家網(wǎng)站選擇商品,下訂單。
2、商家把支付信息,get到支付寶指定的鏈接。
3、終端消費(fèi)者在支付寶的網(wǎng)站上操作付款。
4、付款成功后,支付寶post付款成功的信息到商家預(yù)先提供的地址。
5、支付寶在終端消費(fèi)者付款成功后三秒后,通過get跳回商家指定的鏈接。

第4步跟終端消費(fèi)者操作付款的跳轉(zhuǎn)無關(guān),所以被稱為異步通知。這一步,支付寶期待你返回'success',如果你不返回'success',支付寶會(huì)于4分鐘后再次post付款成功的信息,此后每10分鐘post一次,至少30分鐘內(nèi)如此。如果終端消費(fèi)者付款失敗,異步通知不會(huì)發(fā)生。

通過集成,我知道為什么終端消費(fèi)者付款成功后要等3秒后跳轉(zhuǎn)回商家頁面了,因?yàn)樗犬惒酵ㄖ男畔⑾鹊竭_(dá),先處理訂單,再帶終端消費(fèi)者回到客戶的界面,這樣就可以看到支付成功的頁面了。當(dāng)然付款失敗,異步通知不發(fā)生,訂單狀態(tài)沒有改變,終端消費(fèi)者就只能看到付款失敗的信息。

了解了支付過程,開始設(shè)計(jì)程序。
1、生成商品訂單。終端消費(fèi)者選擇商品生成商品訂單。ID號(hào)要唯一,這個(gè)唯一不是要你采用UUID,而是跟支付寶往來過程唯一即可,從1遞增也可以,只是終端消費(fèi)者能看到這個(gè)id,所以最好采用固定長(zhǎng)度的字符串,終端消費(fèi)者如果知道自己是第一個(gè)客戶,會(huì)不會(huì)心里發(fā)怵?后面會(huì)談到,為了安全不僅不能用遞增,而且至少要6位隨機(jī)碼以上。
2、選擇支付方式。因?yàn)槲覀儍H僅集成了即時(shí)到帳,所以只有支付寶付款一個(gè)選項(xiàng)。把支付方式加入訂單信息,同時(shí)把訂單id post到下一步地址,這一步post,最好采用新開頁面,本頁面彈出對(duì)話框,讓客戶自己選擇支付成功或者支付失敗。
3、發(fā)送支付信息。根據(jù)post過來的訂單號(hào)組合信息,get方式發(fā)送數(shù)據(jù)給支付寶,同時(shí)帶動(dòng)終端消費(fèi)者頁面跳轉(zhuǎn)到支付寶支付頁面。
4、接受異步通知。
5、支付成功后支付寶跳轉(zhuǎn)回來的程序。因?yàn)榛貋頃r(shí)get方式,為避免終端消費(fèi)者看到更多敏感信息,這一步并沒有渲染頁面,而是處理信息,跳轉(zhuǎn)到另外一個(gè)頁面。
6、顯示支付結(jié)果。這個(gè)頁面和第2步讓客戶點(diǎn)擊支付成功跳轉(zhuǎn)的是同一個(gè)。支付失敗,就跳轉(zhuǎn)到一個(gè)說明吧。

alipay.py

import types 
from urllib import urlencode, urlopen 
from hashcompat import md5_constructor as md5<span style="white-space:pre">  </span>#見hashcompact.py 
from config import settings<span style="white-space:pre">     </span>#見config.py 
 
#字符串編解碼處理 
def smart_str(s, encoding='utf-8', strings_only=False, errors='strict'): 
  if strings_only and isinstance(s, (types.NoneType, int)): 
    return s 
  if not isinstance(s, basestring): 
    try: 
      return str(s) 
    except UnicodeEncodeError: 
      if isinstance(s, Exception): 
        return ' '.join([smart_str(arg, encoding, strings_only, 
            errors) for arg in s]) 
      return unicode(s).encode(encoding, errors) 
  elif isinstance(s, unicode): 
    return s.encode(encoding, errors) 
  elif s and encoding != 'utf-8': 
    return s.decode('utf-8', errors).encode(encoding, errors) 
  else: 
    return s 
 
# 網(wǎng)關(guān)地址 
_GATEWAY = 'https://mapi.alipay.com/gateway.do?' 
 
 
# 對(duì)數(shù)組排序并除去數(shù)組中的空值和簽名參數(shù) 
# 返回?cái)?shù)組和鏈接串 
def params_filter(params): 
  ks = params.keys() 
  ks.sort() 
  newparams = {} 
  prestr = '' 
  for k in ks: 
    v = params[k] 
    k = smart_str(k, settings.ALIPAY_INPUT_CHARSET) 
    if k not in ('sign','sign_type') and v != '': 
      newparams[k] = smart_str(v, settings.ALIPAY_INPUT_CHARSET) 
      prestr += '%s=%s&' % (k, newparams[k]) 
  prestr = prestr[:-1] 
  return newparams, prestr 
 
 
# 生成簽名結(jié)果 
def build_mysign(prestr, key, sign_type = 'MD5'): 
  if sign_type == 'MD5': 
    return md5(prestr + key).hexdigest() 
  return '' 
 
 
# 即時(shí)到賬交易接口 
def create_direct_pay_by_user(tn, subject, body, bank, total_fee): 
  params = {} 
  params['service']    = 'create_direct_pay_by_user' 
  params['payment_type'] = '1'    #商品購買,只能選這個(gè) 
   
  # 獲取配置文件 
  params['partner']      = settings.ALIPAY_PARTNER 
  params['seller_id']     = settings.ALIPAY_PARTNER 
  params['seller_email']   = settings.ALIPAY_SELLER_EMAIL 
  params['return_url']    = settings.ALIPAY_RETURN_URL 
  params['notify_url']    = settings.ALIPAY_NOTIFY_URL 
  params['_input_charset']  = settings.ALIPAY_INPUT_CHARSET 
  params['show_url']     = settings.ALIPAY_SHOW_URL 
   
  # 從訂單數(shù)據(jù)中動(dòng)態(tài)獲取到的必填參數(shù) 
  params['out_trade_no'] = tn    # 請(qǐng)與貴網(wǎng)站訂單系統(tǒng)中的唯一訂單號(hào)匹配 
  params['subject']    = subject  # 訂單名稱,顯示在支付寶收銀臺(tái)里的“商品名稱”里,顯示在支付寶的交易管理的“商品名稱”的列表里。 
  params['body']     = body   # 訂單描述、訂單詳細(xì)、訂單備注,顯示在支付寶收銀臺(tái)里的“商品描述”里,可以為空 
  params['total_fee']   = total_fee # 訂單總金額,顯示在支付寶收銀臺(tái)里的“應(yīng)付總額”里,精確到小數(shù)點(diǎn)后兩位 
   
  # 擴(kuò)展功能參數(shù)——網(wǎng)銀提前 
  if bank=='alipay' or bank=='': 
    params['paymethod'] = 'directPay'  # 支付方式,四個(gè)值可選:bankPay(網(wǎng)銀); cartoon(卡通); directPay(余額); CASH(網(wǎng)點(diǎn)支付) 
    params['defaultbank'] = ''     # 支付寶支付,這個(gè)為空 
  else: 
    params['paymethod'] = 'bankPay'   # 默認(rèn)支付方式,四個(gè)值可選:bankPay(網(wǎng)銀); cartoon(卡通); directPay(余額); CASH(網(wǎng)點(diǎn)支付) 
    params['defaultbank'] = bank    # 默認(rèn)網(wǎng)銀代號(hào),代號(hào)列表見http://club.alipay.com/read.php?tid=8681379     
   
 
   
  params,prestr = params_filter(params) 
   
  params['sign'] = build_mysign(prestr, settings.ALIPAY_KEY, settings.ALIPAY_SIGN_TYPE) 
  params['sign_type'] = settings.ALIPAY_SIGN_TYPE 
   
  return _GATEWAY + urlencode(params) 
 
def notify_verify(post): 
  # 初級(jí)驗(yàn)證--簽名 
  _,prestr = params_filter(post) 
  mysign = build_mysign(prestr, settings.ALIPAY_KEY, settings.ALIPAY_SIGN_TYPE) 
 
  if mysign != post.get('sign'): 
    return False 
   
  # 二級(jí)驗(yàn)證--查詢支付寶服務(wù)器此條信息是否有效 
  params = {} 
  params['partner'] = settings.ALIPAY_PARTNER 
  params['notify_id'] = post.get('notify_id') 
 
  gateway = 'https://mapi.alipay.com/gateway.do?service=notify_verify&' 
  verify_result = urlopen(gateway, urlencode(params)).read() 
  if verify_result.lower().strip() == 'true': 
    return True 
  return False 

hashcompact.py

""" 
The md5 and sha modules are deprecated since Python 2.5, replaced by the 
hashlib module containing both hash algorithms. Here, we provide a common 
interface to the md5 and sha constructors, preferring the hashlib module when 
available. 
""" 
 
try: 
  import hashlib 
  md5_constructor = hashlib.md5 
  md5_hmac = md5_constructor 
  sha_constructor = hashlib.sha1 
  sha_hmac = sha_constructor 
except ImportError: 
  import md5 
  md5_constructor = md5.new 
  md5_hmac = md5 
  import sha 
  sha_constructor = sha.new 
  sha_hmac = sha 

config.py

#-*- coding:utf-8 -*- 
 
class settings: 
 # 安全檢驗(yàn)碼,以數(shù)字和字母組成的32位字符 
 ALIPAY_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' 
 
 ALIPAY_INPUT_CHARSET = 'utf-8' 
 
 # 合作身份者ID,以2088開頭的16位純數(shù)字 
 ALIPAY_PARTNER = 'xxxxxxxxxxxxxxxx' 
 
 # 簽約支付寶賬號(hào)或賣家支付寶帳戶 
 ALIPAY_SELLER_EMAIL = 'ls@abc.com' 
 
 ALIPAY_SIGN_TYPE = 'MD5' 
 
 # 付完款后跳轉(zhuǎn)的頁面(同步通知) 要用 http://格式的完整路徑,不允許加?id=123這類自定義參數(shù) 
 ALIPAY_RETURN_URL='http://www.xxx.com/alipay/return/' 
 
 # 交易過程中服務(wù)器異步通知的頁面 要用 http://格式的完整路徑,不允許加?id=123這類自定義參數(shù) 
 ALIPAY_NOTIFY_URL='http://www.xxx.com/alipay/notify/' 

view.py

#確認(rèn)支付 
def pay(request): 
  cbid=request.POST.get('id') 
  try: 
    cb=cBill.objects.get(id=cbid) 
  except ObjectDoesNotExist: 
    return HttpResponseRedirect("/err/no_object") 
   
  #如果網(wǎng)關(guān)是支付寶 
  if cb.cbank.gateway=='alipay': 
      tn=cb.id 
      subject='' 
      body='' 
      bank=cb.cbank.id 
      tf='%.2f' % cb.amount 
      url=create_direct_pay_by_user (tn,subject,body,bank,tf) 
 
  #如果網(wǎng)關(guān)是財(cái)付通 
  elif cb.cbank.gateway=='tenpay': 
    pass 
   
  #去支付頁面 
  return HttpResponseRedirect (url) 
 
#alipay異步通知 
 
@csrf_exempt 
def alipay_notify_url (request): 
  if request.method == 'POST': 
    if notify_verify (request.POST): 
      #商戶網(wǎng)站訂單號(hào) 
      tn = request.POST.get('out_trade_no') 
      #支付寶單號(hào) 
      trade_no=request.POST.get('trade_no') 
      #返回支付狀態(tài) 
      trade_status = request.POST.get('trade_status') 
      cb = cBill.objects.get(pk=tn) 
       
      if trade_status == 'TRADE_SUCCESS': 
        cb.exe() 
        log=Log(operation='notify1_'+trade_status+'_'+trade_no) 
        log.save() 
        return HttpResponse("success") 
      else: 
        #寫入日志 
        log=Log(operation='notify2_'+trade_status+'_'+trade_no) 
        log.save() 
        return HttpResponse ("success") 
    else: 
      #黑客攻擊 
      log=Log(operation='hack_notify_'+trade_status+'_'+trade_no+'_'+'out_trade_no') 
      log.save() 
  return HttpResponse ("fail") 
 
#同步通知 
 
def alipay_return_url (request): 
  if notify_verify (request.GET): 
    tn = request.GET.get('out_trade_no') 
    trade_no = request.GET.get('trade_no') 
    trade_status = request.GET.get('trade_status') 
      
    cb = cBill.objects.get(pk=tn) 
    log=Log(operation='return_'+trade_status+'_'+trade_no) 
    log.save() 
    return HttpResponseRedirect ("/public/verify/"+tn) 
  else: 
    #錯(cuò)誤或者黑客攻擊 
    log=Log(operation='err_return_'+trade_status+'_'+trade_no) 
    log.save() 
    return HttpResponseRedirect ("/") 
 
 
#外部跳轉(zhuǎn)回來的鏈接session可能丟失,無法再進(jìn)入系統(tǒng)。 
#客戶可能通過xxx.com操作,但是支付寶只能返回www.xxx.com,域名不同,session丟失。 
def verify(request,cbid): 
  try: 
    cb=cBill.objects.get(id=cbid) 
    #如果訂單時(shí)間距現(xiàn)在超過1天,跳轉(zhuǎn)到錯(cuò)誤頁面! 
    #避免網(wǎng)站信息流失 
     
    return render_to_response('public_verify.html',{'cb':cb},RequestContext(request)) 
  except ObjectDoesNotExist: 
    return HttpResponseRedirect("/err/no_object") 

view.py中的代碼僅供參考!

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。

相關(guān)文章

  • python:動(dòng)態(tài)路由的Flask程序代碼

    python:動(dòng)態(tài)路由的Flask程序代碼

    今天小編就為大家分享一篇python:動(dòng)態(tài)路由的Flask程序代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • python爬蟲實(shí)戰(zhàn)steam加密逆向RSA登錄解析

    python爬蟲實(shí)戰(zhàn)steam加密逆向RSA登錄解析

    今天帶來爬蟲實(shí)戰(zhàn)的文章。在挑選游戲的過程中感受學(xué)習(xí),讓你突飛猛進(jìn)。本文主要實(shí)現(xiàn)用Python逆向登錄世界上最大的游戲平臺(tái)源碼分享,了解steam加密手段有多高明
    2021-10-10
  • Python字符串中添加、插入特定字符的方法

    Python字符串中添加、插入特定字符的方法

    這篇文章主要介紹了Python字符串中添加、插入特定字符的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-09-09
  • python實(shí)現(xiàn)圖像拼接功能

    python實(shí)現(xiàn)圖像拼接功能

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)圖像拼接功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • Python中內(nèi)建函數(shù)的簡(jiǎn)單用法說明

    Python中內(nèi)建函數(shù)的簡(jiǎn)單用法說明

    這篇文章主要介紹了Python中內(nèi)建函數(shù)的簡(jiǎn)單用法說明,包括apply()、filter()、reduce()、map()四個(gè)函數(shù)的用法講解,需要的朋友可以參考下
    2016-05-05
  • 用python實(shí)現(xiàn)一幅春聯(lián)實(shí)例代碼

    用python實(shí)現(xiàn)一幅春聯(lián)實(shí)例代碼

    大家好,本篇文章主要講的是用python實(shí)現(xiàn)一幅春聯(lián)實(shí)例代碼,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-01-01
  • python實(shí)現(xiàn)自動(dòng)售貨機(jī)

    python實(shí)現(xiàn)自動(dòng)售貨機(jī)

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)自動(dòng)售貨機(jī),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Python多進(jìn)程機(jī)制實(shí)例詳解

    Python多進(jìn)程機(jī)制實(shí)例詳解

    這篇文章主要介紹了Python多進(jìn)程機(jī)制,以實(shí)例形式詳細(xì)分析了Python多進(jìn)程機(jī)制的原理與實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2015-07-07
  • Pytorch模型微調(diào)fine-tune詳解

    Pytorch模型微調(diào)fine-tune詳解

    微調(diào)(fine-tune)通過使用在大數(shù)據(jù)上得到的預(yù)訓(xùn)練好的模型來初始化自己的模型權(quán)重,從而提升精度,這篇文章主要介紹了Pytorch模型微調(diào)(fine-tune),需要的朋友可以參考下
    2023-01-01
  • 10招!看骨灰級(jí)Pythoner玩轉(zhuǎn)Python的方法

    10招!看骨灰級(jí)Pythoner玩轉(zhuǎn)Python的方法

    這篇文章主要介紹了10招!看骨灰級(jí)Pythoner如何玩轉(zhuǎn)Python,需要的朋友可以參考下
    2019-04-04

最新評(píng)論

鄯善县| 吴旗县| 武冈市| 灵宝市| 兰溪市| 合山市| 清涧县| 武安市| 沈丘县| 隆昌县| 台中市| 淮滨县| 伽师县| 中阳县| 安图县| 宾川县| 兖州市| 新沂市| 普陀区| 宜丰县| 上林县| 西安市| 定边县| 白水县| 贵港市| 阿坝县| 海兴县| 子长县| 陆丰市| 株洲县| 高阳县| 谢通门县| 苏尼特右旗| 松原市| 灵武市| 马尔康县| 金沙县| 宁化县| 土默特右旗| 花莲县| 开化县|