亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

利用Python的Flask框架來構(gòu)建一個(gè)簡單的數(shù)字商品支付解決方案

 更新時(shí)間:2015年03月31日 10:22:07   作者:Jeff Knupp  
這篇文章主要介紹了利用Python的Flask框架來構(gòu)建一個(gè)簡單的數(shù)字商品支付解決方案,文中用極簡的代碼展示了一個(gè)flask框架下的支付模版,需要的朋友可以參考下

作為一個(gè)程序員,我有時(shí)候忘了自己所具有的能力。當(dāng)事情沒有按照你想要的方式發(fā)展時(shí),卻很容易忘記你有能力去改變它。昨天,我意識到,我已經(jīng)對我所出售的書的付款處理方式感到忍無可忍了。我的書完成后,我使用了三個(gè)不同的數(shù)字商品支付處理器,在對它們?nèi)齻€(gè)都感到不滿后,我用Python和Flask,兩個(gè)小時(shí)的時(shí)間寫出了我自己的解決方案。沒錯(cuò)!兩個(gè)小時(shí)!現(xiàn)在,這個(gè)系統(tǒng)支撐著我的書籍付費(fèi)流程,整個(gè)過程難以置信的簡單,你可以在20秒內(nèi)購買書籍并開始閱讀。

往下看,看我是如何在一夜之間完成我自己的數(shù)字商品支付解決方案的。
支付處理器的付款問題

在我開始賣書的時(shí)候,我綜合用了兩種支付服務(wù)(一種是信用卡,另一種是PayPal)。最終,我發(fā)現(xiàn)了一個(gè)可以支持兩者的處理方式??墒俏覍λ鼈兌疾粷M意。最常用的那個(gè)支付處理器,要求用戶在銷售商的系統(tǒng)中創(chuàng)建一個(gè)賬戶,并且輸入他們的郵箱地址(盡管郵箱并沒有用)。

另外,我嘗試使用Google Analytics 在全部的訪問中追蹤訪客,包括他們的結(jié)賬過程,這一過程也很艱辛。我經(jīng)常感覺到,如果我能夠讓它工作起來,并且能夠在我的書籍頁面進(jìn)行A/B測試,我能極大地提高銷量。但是因?yàn)椴荒芎芎玫淖粉櫍揖蜎]那么走運(yùn)了。

最后,使用三個(gè)不同的支付處理器,發(fā)送書籍更新非常耗時(shí)。沒有一個(gè)能很好的支持更新,而我希望有個(gè)“一鍵”解決方案來發(fā)送我的書籍更新。我就沒找到一個(gè)類似的服務(wù)。
歐耶,我是個(gè)程序員

昨天,當(dāng)我收到一個(gè)顧客的郵件,抱怨支付過程是如何的困難并且告訴我可能因此損失了很多銷量后,我忍無可忍了。我決定整一個(gè)自己的數(shù)字商品管理解決方案。我需要做到下面這樣了流程:

當(dāng)客戶點(diǎn)擊“Buy Now”按鈕后,他們應(yīng)該僅僅被要求輸入他們的email地址和信用卡信息。點(diǎn)擊“Confirm”后被帶到一個(gè)獨(dú)一無二的URL去下載書籍(專門為了這次交易而生成的)。一封包含這個(gè)URL的郵件應(yīng)該被發(fā)送給客戶(防止用戶需要重新下載這本書)。對他們重復(fù)下載的次數(shù)應(yīng)該有個(gè)限制(5次)。交易信息和客戶信息應(yīng)該被存放在數(shù)據(jù)庫中,發(fā)送書籍更新應(yīng)該只是一個(gè)命令的事。

顯然,這并不是那么的復(fù)雜。最復(fù)雜的部分是動態(tài)生成導(dǎo)向特定書籍版本的獨(dú)一無二的URL。其他的事情都挺簡單的。
“Flask前來救援”或是“一個(gè)100行代碼的數(shù)字商品支付解決方案”

劇透:程序的最終結(jié)果正好是100行代碼。對于這種規(guī)模的web應(yīng)用,F(xiàn)lask是個(gè)很好的選擇。并不需要大量的模板(cough就像 Django cough),但是有很多很好的插件作為支持。Bottle會是另外一個(gè)不錯(cuò)的選擇,但是我最近都在用Flask,所以我就選它了。

開始的時(shí)候,我需要決定如何來存放用戶和交易信息。我決定使用SQLAlchemy,因?yàn)?a target="_blank" >sandman的原因,我比較熟悉它SQLAlchemy。Flask有一個(gè)插件叫Flask-SQLAlchemy,這使得結(jié)合使用兩者非常容易。因?yàn)槲也恍枰魏位ㄉ诘臄?shù)據(jù)庫操作,我選擇SQLite作為我的后臺數(shù)據(jù)庫。

決定這樣做之后,我創(chuàng)建了一個(gè)app.py 文件并且創(chuàng)建了如下的模型:

 
class Product(db.Model):
  __tablename__ = 'product'
  id = db.Column(db.Integer, primary_key=True)
  name = db.Column(db.String)
  file_name = db.Column(db.String)
  version = db.Column(db.String)
  is_active = db.Column(db.Boolean, default=True)
  price = db.Column(db.Float)
 
class Purchase(db.Model):
  __tablename__ = 'purchase'
  uuid = db.Column(db.String, primary_key=True)
  email = db.Column(db.String)
  product_id = db.Column(db.Integer, db.ForeignKey('product.id'))
  product = db.relationship(Product)
  downloads_left = db.Column(db.Integer, default=5)

在向數(shù)據(jù)庫添加了5種不同版本的書籍后(我創(chuàng)建了一個(gè)populate_db.py 文件,并把這些版本作為SQLAlchemy模型來添加進(jìn)數(shù)據(jù)庫),我需要決定我究竟要如何處理支付。幸運(yùn)的是,Stripe讓接受一個(gè)信用卡變得非常簡單,并且我也已經(jīng)有了一個(gè)他們的賬戶。他們的”checkout.js”方案會在你的頁面上創(chuàng)建一個(gè)表單和按鈕。當(dāng)點(diǎn)擊這個(gè)按鈕時(shí),一個(gè)簡潔又引人注目的浮動層會彈出來。

2015331102015017.jpg (1412×887)

這個(gè)表單的action 屬性指向你的站點(diǎn)的一個(gè)頁面,當(dāng)用戶完成支付后就會被帶到那里。我在我的書籍銷售頁面添加了5個(gè)這樣的按鈕,還有一個(gè)隱藏的表單欄,包含了被交易產(chǎn)品的id(product_id)(1-5之間的一個(gè)整數(shù))
處理支付

顯然,我的應(yīng)用需要一個(gè)后端來處理一次成功付款。我添加了以下這些函數(shù)來完成這一目的:

 
@app.route('/buy', methods=['POST'])
def buy():
  stripe_token = request.form['stripeToken']
  email = request.form['stripeEmail']
  product_id = request.form['product_id']
  product = Product.query.get(product_id)
  try:
    charge = stripe.Charge.create(
        amount=int(product.price * 100),
        currency='usd',
        card=stripe_token,
        description=email)
  except stripe.CardError, e:
    return """<html><body><h1>Card Declined</h1><p>Your chard could not
    be charged. Please check the number and/or contact your credit card
    company.</p></body></html>"""
  print charge
  purchase = Purchase(uuid=str(uuid.uuid4()),
      email=email,
      product=product)
  db.session.add(purchase)
  db.session.commit()
  message = Message(
      subject='Thanks for your purchase!',
    sender="jeff@jeffknupp.com",
    html="""<html><body><h1>Thanks for buying Writing Idiomatic Python!</h1>
<p>If you didn't already download your copy, you can visit
<a >your private link</a>. You'll be able to
download the file up to five times, at which point the link will
expire.""".format(purchase.uuid),
    recipients=[email])
  with mail.connect() as conn:
    conn.send(message)
  return redirect('/{}'.format(purchase.uuid))

正如你所看到的,我寫代碼的時(shí)候有點(diǎn)偷懶了(因?yàn)槲艺趹嵟木幊獭┦紫?,我有一個(gè)內(nèi)聯(lián)HTML,在付費(fèi)不成功時(shí)返回,還有已購買成功時(shí)返回郵箱。這些東西應(yīng)該被放在一個(gè)全局變量,或者,更好的方法是放在一個(gè)單獨(dú)的文件中。另外,在創(chuàng)建Purchase 時(shí)我并沒有進(jìn)行任何的錯(cuò)誤檢查。但是實(shí)際上,唯一可能出錯(cuò)的地方是嘗試插入重復(fù)的 uuid,但是我并不擔(dān)心,因?yàn)榘l(fā)生的幾率太低了(潛臺詞:微乎其微)。

你可以看的我使用了一個(gè)mail 對象,這個(gè)對象來自于Flask-Mail包,這個(gè)插件讓發(fā)送郵件變得輕松。我就設(shè)置它使用GMail作為服務(wù)器,然后所有東西都可以正常工作了。
好吧,現(xiàn)在該給我書了

現(xiàn)在,支付的部分已經(jīng)搞定,我需要添加一個(gè)后端功能,在完成支付后初始化下載。因?yàn)槲沂褂肬UID作為主鍵,所以我同樣可以使用它作為URL。當(dāng)有人訪問包含UUID的URL時(shí),我需要檢查該UUID是不是包含在數(shù)據(jù)庫中。如果是的話,提供書籍文件并且把剩余下載(downloads_left)次數(shù)屬性減少1次。如果不是的話,就返回404錯(cuò)誤。下面是我寫的代碼:
 

@app.route('/<uuid>')
def download_file(uuid):
  purchase = Purchase.query.get(uuid)
  if purchase:
    if purchase.downloads_left <= 0:
      return """<html><body><h1>No downloads left!</h1><p>You have
      exceeded the allowed number of downloads for this file. Please email
      jeff@jeffknupp.com with any questions.</p></body></html>"""
    purchase.downloads_left -= 1
    db.session.commit()
    return send_from_directory(directory='files',
        filename=purchase.product.file_name, as_attachment=True)
  else:
    abort(404)

非常直觀。使用UUID作為一個(gè)URL變量,尋找交易信息。如果存在,就檢查是否還有可用下載次數(shù),然后提供所購買的文件。否則,等著你的是404錯(cuò)誤。

最后,我需要我需要添加一個(gè)測試來讓我可以模擬交易過程。下面是測試代碼和讓這個(gè)app運(yùn)行的代碼:

@app.route('/test')
def test():
  return """<http><body><form action="buy" method="POST">
<script
  src="https://checkout.stripe.com/checkout.js" class="stripe-button"
  data-key="pk_test_w3qNBkDR8A4jkKejBmsMdH34"
  data-amount="999"
  data-name="jeffknupp.com"
  data-description="Writing Idiomatic Python 3 PDF ($9.99)">
</script>
<input type="hidden" name="product_id" value="2" />
</form>
</body>
</html>
"""
if __name__ == '__main__':
  sys.exit(app.run(debug=True))

能力越大…責(zé)任越大!

實(shí)際上我對于自己能如此快速簡單讓這一切工作起來感到吃驚。整個(gè)應(yīng)用程序包含在一個(gè)100行代碼的文件中。而且它替代了我每天使用的那些重要服務(wù),我對那些服務(wù)一直都不滿意。最后,我可以追蹤交易,沒有任何問題,這讓我確信自己可以提高銷量。

作為一個(gè)開發(fā)者,能意識到你有能力塑造我們和數(shù)字世界的交互是很好的一件事。比方說,我會忘記,如果有一些科技不能按照我預(yù)想的方式去工作,我有能力改變它。從自動化機(jī)械式的任務(wù)比如輸入數(shù)據(jù),到自動排序和整理電子郵件,開發(fā)者們有能力去簡化他們每天的工作。

擁有Flask這樣的工具對解決這些問題非常重要。正如像作為程序員那樣進(jìn)步,你應(yīng)該建立你的一套解決“核心”問題的工具集。Flask就是很好的例子,因?yàn)榇掖颐γΦ钠礈愐粋€(gè)web應(yīng)用是一件司空見慣的事情。

當(dāng)然,分享你的作品同樣非常的重要。如果我做一些東西,對我自己有用,但沒有去分享給別人,我就會怠慢?!胺窒怼辈粌H僅意味著”把項(xiàng)目放進(jìn)一個(gè)GitHub公共倉庫“。你還需要讓大家知道有這個(gè)東西。從郵件列表到論壇再到個(gè)人博客,從來都不缺少讓大家知道你創(chuàng)造了一些東西的途徑。我總是設(shè)法回饋社區(qū),因?yàn)槲覐闹械玫搅撕芏鄸|西。

相關(guān)文章

  • Python簡單遍歷字典及刪除元素的方法

    Python簡單遍歷字典及刪除元素的方法

    這篇文章主要介紹了Python簡單遍歷字典及刪除元素的方法,結(jié)合實(shí)例形式分析了Python遍歷字典刪除元素的操作方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2016-09-09
  • 解析Pytest3種配置文件方式

    解析Pytest3種配置文件方式

    pytest的主配置文件,可以改變pytest的默認(rèn)行為,本文主要介紹了解析Pytest3種配置文件方式,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • centos6.4下python3.6.1安裝教程

    centos6.4下python3.6.1安裝教程

    這篇文章主要為大家詳細(xì)介紹了centos6.4下python3.6.1的安裝教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • python?tkinter中的Frame控件用法詳解

    python?tkinter中的Frame控件用法詳解

    Tkinter中的Frame控件是一個(gè)用于組織和管理其他控件的容器,它可以將其他控件放置在自己內(nèi)部,用于創(chuàng)建更復(fù)雜的用戶界面,要?jiǎng)?chuàng)建一個(gè)Frame控件,可以使用Tkinter的Frame類,所以本文就通過一個(gè)簡單的示例給大家介紹一下
    2023-08-08
  • 解決django migrate報(bào)錯(cuò)ORA-02000: missing ALWAYS keyword

    解決django migrate報(bào)錯(cuò)ORA-02000: missing ALWAYS keyword

    這篇文章主要介紹了解決django migrate報(bào)錯(cuò)ORA-02000: missing ALWAYS keyword,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-07-07
  • Python獲取指定日期是"星期幾"的6種方法

    Python獲取指定日期是"星期幾"的6種方法

    在Python進(jìn)行數(shù)據(jù)分析時(shí),按照日期進(jìn)行分組匯總也是被需要的,比如會找到銷量的周期性規(guī)律。本文將以2022-02-22為例,演示Python獲取指定日期是“星期幾”的6種方法,需要的可以參考一下
    2022-03-03
  • 基于Python實(shí)現(xiàn)全自動二維碼識別

    基于Python實(shí)現(xiàn)全自動二維碼識別

    這篇文章主要為大家詳細(xì)介紹了如何基于Python實(shí)現(xiàn)全自動二維碼識別功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-11-11
  • Python生成掃雷地圖的方法

    Python生成掃雷地圖的方法

    這篇文章主要為大家詳細(xì)介紹了Python生成掃雷地圖的方法,并非游戲?qū)崿F(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • python輸出帶顏色字體實(shí)例方法

    python輸出帶顏色字體實(shí)例方法

    在本篇文章里小編給大家整理了關(guān)于python輸出帶顏色字體實(shí)例以及相關(guān)代碼,有需要的朋友們可以學(xué)習(xí)參考下。
    2019-09-09
  • 解決Python3.8用pip安裝turtle-0.0.2出現(xiàn)錯(cuò)誤問題

    解決Python3.8用pip安裝turtle-0.0.2出現(xiàn)錯(cuò)誤問題

    turtle庫是python的基礎(chǔ)繪圖庫,這個(gè)庫被介紹為一個(gè)最常用的用來給孩子們介紹編程知識的方法庫,這篇文章主要介紹了解決Python3.8用pip安裝turtle-0.0.2出現(xiàn)錯(cuò)誤問題,需要的朋友可以參考下
    2020-02-02

最新評論