DjangoはAlipayサンドボックス操作を実装します
環境は必須モジュールです
- Django == 3.1.0
- python == 3.7.4
- python-alipay-sdk = 2.0.1
必須
- モジュールpython-alipay-sdk = 2.0.1をダウンロードします
- 非公式のAlipayPython SDKを文書化する:https://github.com/fzlee/alipay/blob/master/README.zh-hans.md#alipay.trade.page.pay
サンドボックス環境の構成
- Alipayオープンプラットフォーム---->開発者センター->開発サービス---->サンドボックス
- RSA2キーの生成とアップロードは、公式アドレスを参照してください:https://opendocs.alipay.com/open/291/105971
- Alipay Open Platform Development Assistantのダウンロードアドレスhttps://opendocs.alipay.com/open/291/introduceをダウンロードして、ダウンロード後に秘密鍵を生成します[外部リンクの画像転送に失敗しました。ソースサイトに盗難防止チェーンメカニズムがある可能性があります。画像を直接保存することをお勧めしますアップロード(img-iAJ4s57z-1602600230093)(C:\ Users \ ASUS \ AppData \ Roaming \ Typora \ typora-user-images \ image-20201013215751437.png)]
[外部リンク画像の転送に失敗しました。元のサイトにリーチ防止リンクメカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします(img-RLkaGka3-1602600315452)(C:%5CUsers%5CASUS%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images% 5Cimage-20201013215646909.png#pic_center)]
)
4.アプリケーションの公開鍵をAlipayにコピーします
[外部リンクの画像転送に失敗しました。ソースサイトにホットリンク防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします(img-pm1umRDQ-1602600230099)(C:\ Users \ ASUS \ AppData \ Roaming \ Typora \ typora-user-images \ image-20201013220238000.png)]
[外部リンク画像の転送に失敗しました。ソースサイトにリーチ防止リンクメカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします(img-xIM2Wwqr-1602600230101)(C:\ Users \ ASUS \ AppData \ Roaming \ Typora \ typora-user-images \ image-20201013220309533.png)]
[外部リンクの画像転送に失敗しました。ソースサイトにホットリンク防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします(img-CZRSx4tY-1602600230104)(C:\ Users \ ASUS \ AppData \ Roaming \ Typora \ typora-user-images \ image-20201013220359867.png)]
5.アプリでAlipay公開鍵開発アシスタントの秘密鍵を構成します
- [外部リンク画像の転送に失敗しました。ソースサイトにホットリンク防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします(img-hzEeNDd6-1602600230107)(C:\ Users \ ASUS \ AppData \ Roaming \ Typora \ typora-user-images \ image-20201013220610210.png)]
- Djangoアプリでフォルダを作成し、Alipay公開キーを配置します(外部リンクの画像転送に失敗しました。ソースサイトに盗難防止チェーンメカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします(img-Bg9hMEFa-1602600230111)(C:\ Users \ ASUS) \ AppData \ Roaming \ Typora \ typora-user-images \ image-20201013221108217.png)]
- Djangoアプリでフォルダを作成し、開いているプラットフォームの秘密鍵を配置します(外部リンクの画像転送が失敗し、ソースサイトに盗難防止チェーンメカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします(img-0aGqpG4B-1602600230112)(C:\ Users \ ASUS \ AppData \ Roaming \ Typora \ typora-user-images \ image-20201013221548593.png)]
Djangoモデル
#支付利态表 クラスStatus(BaseModel): name = models.CharField(max_length = 32) class Meta: db_table = 'status' #支付表 class Order(BaseModel): out_trade_no = models.CharField(max_length = 60) trada_no = models .CharField(max_length = 60、null = True、blank = True) goods = models.ForeignKey(Goods、on_delete = models.CASCADE) user = models.ForeignKey(User、on_delete = models.CASCADE) goods_num = models.IntegerField() status = models.ForeignKey(Status、on_delete = models.CASCADE) class Meta: db_table = 'order'
Djangoビューの構成
- 所いっぱい的包importuuid import redis from app01.views import login_serializer from alipay import AliPay、AliPayConfig123
#ファイルを開くための絶対パス{}は、ここから先に進むことを意味します app_private_key_string = open( '{} \\ app02 \\ alipay_key \\ app_private_key'.format(settings.BASE_DIR))。read() alipay_public_key_string = open('()\\ app02 \\ alipay_key \\ alipay_public'.format(settings.BASE_DIR))。read()12
[外部リンクの画像転送に失敗しました。ソースサイトにホットリンク防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします(img-TU8ck5hJ-1602600230116)(C:\ Users \ ASUS \ AppData \ Roaming \ Typora \ typora-user-images \ image-20201013222520219.png)]
アリペイ=アリペイ( APPID = "2016102500759596"、 app_notify_url =なし、#デフォルトのコールバックURL app_private_key_string = app_private_key_string、 #アリペイの公開鍵で、Alipayのリターン・メッセージではなく、あなた自身の公開鍵の使用を確認する alipay_public_key_string = alipay_public_key_string、 sign_type = "RSA2を"、#RSAまたはRSA2 debug = True、#デフォルトFalse config = AliPayConfig(timeout = 15)#オプション、リクエストタイムアウト時間 )123456789
3.コメントされたコードは削除できます
#支払い クラスAlipayView(APIView): def post(self、request): #print(request.data) token = request.data.get( 'token') count = request.data.get( 'count') goods_info = request .data.get( 'goods_info') #print(goods_info) #注文番号uuidは一意で一意です out_trade_no = str(uuid.uuid4()) #初期注文金額 total_amount = 0 user_info = login_serializer.loads(token) user_id = user_info。 get( 'user_id') #複数のIDに使用するかどうかを決定し、数値で除算する if goods_info.find( '、')!= -1: order_list = [] for i in goods_info.split( '、'): print(i) #バッチ追加リスト #出力IDを循環 ##ショッピングカート内のアイテムの数を取得し ます#goods_count = r3.hget(user_id、i).decode() ## iに等しいアイテムを取得します #goods_obj = Goods.objects.get(pk = i) ##合計価格を計算します #total_amount + = int(goods_obj.price)* int(goods_count)\ #リスト追加タイプ order_list.append(Order( out_trade_no = out_trade_no、 goods_id = i、 user_id = user_id、 goods_num = count、 status_id = 1、 )) print(order_list) ser = Order.objects.bulk_create(order_list) #ser.save() else: #print(r3.hget(user_id、goods_info)) #goods_count = r3.hget(user_id、goods_info).decode() #goods_obj =商品。 objects.get(pk = goods_info) #total_amount + = int(goods_obj.price)* int(goods_count) #print(total_amount) #単取 ser = OrderModelSer(data = { "out_trade_no":out_trade_no、 "goods":goods_info、 "user":user_id、 "goods_num":count、 "status":1 }) if ser.is_valid(): ser。save() else: 印刷(ser.errors) #件名の 件名= "京东" コンピュータのウェブサイトの支払いのために#は、あなたがhttps://openapi.alipay.com/gateway.do?+ order_stringにジャンプする必要が order_string = alipay.api_alipay_trade_page_pay( out_trade_no = out_trade_no、 TOTAL_AMOUNT = count、 subject = subject、 return_url = "http://127.0.0.1:8000/app02/callback_alipay"、notify_url =" http://127.0.0.1:8000/app02/callback_alipay"#オプション、入力されていない場合はデフォルトを使用通知URL ) #ステッチデータ #print(order_string) pay_url = 'https://openapi.alipaydev.com/gateway.do?'+ order_string #パラメータジャンプを使用したルート #print(pay_url) return Response({'pay_url':pay_url、 'msg': 'OK'、 "code":200})12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
[外部リンク画像の転送に失敗しました。ソースサイトにリーチ防止リンクメカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします(img-m6WYKp5g-1602600230119)(C:\ Users \ ASUS \ AppData \ Roaming \ Typora \ typora-user-images \ image-20201013223018379.png)]
4.0 4.0
#支払い クラス後のコールバックアドレスCallBackAlipayView(APIView): def get(self、request): print(request.query_params) print( "---------------------- -------- ") # request.query_params.get(" sign ")の場合にデータがあるかどうかを判断します: #request.query_params.get(" out_trade_no ")のiの場合:#print (request.query_params.get ( "out_trade_no")) #注文番号を取得 queryset = Order.objects.get(out_trade_no = request.query_params.get( "out_trade_no")) #注文ステータスを購入した部分変更に変更 ser = OrderModelSer(instance = queryset、data = {"status":2}、partial = True) if ser.is_valid(): ser。保存する() else: print(ser.errors) return Response({'msg': 'OK'、 "data":request.query_params})1234567891011121314151617181920
[外部リンクの画像転送に失敗しました。ソースサイトにホットリンク防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします(img-AFbrRopL-1602600230122)(C:\ Users \ ASUS \ AppData \ Roaming \ Typora \ typora-user-images \ image-20201013223126443.png)]
通話インターフェース
addcart(){ let data = new FormData(); data.append( "token"、sessionStorage.getItem( "token")) data.append( "goods_info"、this.check) data.append( "count"、this.count2)axios ({ url: "http:/ /127.0.0.1:8000/app02/alipay "、 method: 'post'、 data:data })。then(res => { console.log(res.data) if(res.data.code === 200) { window.location.href = res.data.pay_url } }) }、12345678910111213141516
1
と呼ばれるページ
<template> <div> <div id = "app"> <div class = "header_con"> <div class = "header"> <div class = "welcome fl">欢迎来到美多商城!</ div> <div class = "fr"> <div v-if = "username" class = "login_btn fl"> 欢迎您:<em> { {username}} </ em> <span> | </ span> <a @ click = "logout">退出</a> </ div> <div v-else class = "login_btn fl"> <ahref = "login.html">登录</a> <span> | </ span> <ahref = "register.html ">注册</a> </ div> = "register.html"> <div class = "user_link fl"> <span> | </ span> <ahref = "user_center_info.html " >用户中心</a> <span> | </ span> <ahref = "cart.html ">我的购物车</a> <span> | </ span> <ahref = "user_center_order.html">我的订単</a> </ div> </ div> </ div> </ div> <div class = "search_bar clearfix"> <a href="index.html" class="logo fl"> <img src = "/ static / images / logo.png"> </a> <div class = "sub_page_name fl"> |&nbsp;&nbsp;&nbsp ;&nbsp;购物车</ div> <form method = "get" action = "/ search.html" class = "search_con fr mt40"> <input type = "text" class = "input_text fl" name = "q" placeholder = "搜索商品 "> <input type = "submit" class = "input_btn fr" name = "" value = "搜索"> </ form> </ div> <divclass = "total_count">下品<em> { {cart.length}} </ em >件</ div> <ul class = "cart_list_th clearfix"> <liclass = "col01">商品名</ li> <liclass = "col03">商品价格</ li> <li class = "col04" > 並列</ li> < liclass = "col05">小计</ li> <liclass = "col06">操作</ li> </ ul> <ul class = "cart_list_td clearfix" v-for = " (sku、index)カート内 "> <li class = "col01"> <input type = "checkbox" name = "" v-model = "check":value = "sku.id" @ click = "checkbox(sku.id、sku.count、sku.price ) "> </ li> <li class = "col02"> <img:src = "'http://127.0.0.1:8000'+sku.img"> </ li> <li class = "col03"> { {sku.name}} </ li> <li class = "col05"> { {sku.price}}元</ li> <li class = "col06"> <div class = "num_add"> <a @click = "on_add(sku.id)" class = "add fl"> + </a> <input v-model = "sku.count" @ focus = "origin_input = sku.count" @blur = "on_input(index)" type = "text" class = "num_show fl"> <a @click = "on_minus(sku.id)" class = "minus fl">-</a> </ div> </ li> <li class = "col07"> { {sku.price * sku.count}}元</ li> <li class = "col08"> <a @ click = "del(sku.id)">删除</a> </ li> </ ul> <ul class = "settlements"> <li class = "col01"> <input type = "checkbox" @ click = "check_count" v-model = "isChecked"> </ li> <liclass = "col02">全選択</ li> <liclass = "col03">合计(不含运费):<span>¥</ span> <em> { {count2}} </ em> <br>共计<b> { {total_selected_count}} </ b>件商品 </ li> <li class = "col04"> <a @click ="addcart">輸出輸入</a> </ li> </ ul> </ div> <fooder> </ fooder> </ div> </ template> <script> import axios from'axios ' import fooder from' ../ components / Fooder ' export default { name: "Cart"、 data(){ return { カート:[ ]、 チェック:[]、 ユーザー名: ""、 total_selected_amount: ""、 total_selected_count: ""、 on_selected_all: ""、 selected_all: ""、 count2:0、 isChecked:false、 } }、 components:{ 'fooder':fooder }、 methods:{ del(goods_id){ let data = new FormData(); data.append( "token"、sessionStorage.getItem( "token")) data.append( "goods_id"、goods_id)axios ({ url: 'http://127.0.0.1:8000 / app02 / delcart '、 data:データ })。then(res => { console.log(res) this。$ router.go(0) }) }、 addcart(){ let data = new FormData(); data.append( "token"、sessionStorage.getItem( "token")) data.append( "goods_info"、this.check) data.append( "count"、this.count2)axios ({ url: "http:/ / 127.0.0.1:8000 / app02 / alipay "、 メソッド: 'post'、 データ:データ })。then(res => { console.log(res.data) if(res.data.code === 200){ console.log(res) this。$ router.go(0) window.location.href = res.data.pay_url } }) }、 on_add(goods_id){ let data = new FormData(); data.append( "token"、sessionStorage.getItem( "token")) data.append( "goods_id"、goods_id)axios ({ url: 'http://127.0.0.1:8000 / app02 / addcart '、 メソッド: 'post'、 data:data })。then(res => { }) }、 on_minus(goods_id){ let data = new FormData(); data.append( "token"、sessionStorage.getItem( "token")) data.append( "goods_id"、goods_id)axios ({ url: 'http://127.0.0.1:8000 / app02 / minuscart '、 メソッド: 'post'、 data:data })。then(res => { console.log(res) this。$ router.go(0) }) }、 show(){ axios({ url: 'http://127.0.0.1: 8000 / app02 / showcart '、 メソッド:' get '、 params:{"token":sessionStorage.getItem( "token ")} })。then(res => { console.log(res) this.cart = res.data.data }) }、 //すべてを選択して合計価格を呼び出す check_count(){ //デフォルト値はfalse this.count2 = 0; this.check = []; if(this.isChecked){ this.check = [] } else { this.cart.forEach(item => { console.log(item.id); this.check.push(item.id); this.count() }) } }、 //合計価格を計算する count(){ // let count = 0 let this.count2 = 0 for(let i in this.cart){ console.log(this.cart [i] ) this.count2 + = this.cart [i] .price * this.cart [i] .count } }、 //ラジオボタンの チェックボックスを計算する(gid、count、price){ //最初の実行は空ですfalse console.log(this.check) if(this.check.includes(gid)){ //含まれている場合は、選択されていることを意味し、もう一度クリックしてfalseを削除し、対応するものを減算します価格 this.count2- =カウント*価格 this.check.splice(this.check.indexOf(gid)、1) } else { //プッシュすると、追加がtrueになります this.check.push [gid] //合計金額を計算し、 this.count2 + = count * price } }、 }、 created(){ this.show() } } </ script> <style scoped > </ style>を クリックして削除し、falseを削除して減算します。対応する価格に移動します this.count2- = count * price this.check.splice(this.check.indexOf(gid)、1) }、 }、 } else { //プッシュとは、追加がtrueになることを意味します this.check.push [gid] //合計価格を計算し、 this.count2 + = count * price }選択して追加します。 created(){ this.show() } } </ script> <スタイルスコープ> </ style>
PS:Pythonの学習教材が必要な場合は、以下のリンクをクリックして自分で入手できます
完全なコードは、以下のリンクをクリックして入手できます〜
Pythonの無料学習資料とグループコミュニケーションの回答クリックして参加