欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Django实现支付宝沙箱操作

程序员文章站 2022-01-13 10:55:40
Django实现支付宝沙箱操作环境即所需模块Django == 3.1.0python == 3.7.4python-alipay-sdk=2.0.1所需下载模块 python-alipay-sdk=2.0.1文档 非官方支付宝 Python SDK: https://github.com/fzlee/alipay/blob/master/README.zh-hans.md#alipay.trade.page.pay沙箱环境配置在支付宝开放平台----&g...

Django实现支付宝沙箱操作

环境即所需模块

  1. Django == 3.1.0

  2. python == 3.7.4

  3. python-alipay-sdk=2.0.1

所需

  1. 下载模块 python-alipay-sdk=2.0.1
  2. 文档 非官方支付宝 Python SDK: https://github.com/fzlee/alipay/blob/master/README.zh-hans.md#alipay.trade.page.pay

沙箱环境配置

  1. 在支付宝开放平台---->开发者中心—>开发服务---->沙箱
  2. RSA2密钥生成并上传 参考官方地址:https://opendocs.alipay.com/open/291/105971
  3. 下载支付宝开放平台开发助手
    1. 下载地址https://opendocs.alipay.com/open/291/introduce
    2. 下载后生成秘钥
    3. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iAJ4s57z-1602600230093)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20201013215751437.png)]


Django实现支付宝沙箱操作
Django实现支付宝沙箱操作
Django实现支付宝沙箱操作
Django实现支付宝沙箱操作
Django实现支付宝沙箱操作
Django实现支付宝沙箱操作
Django实现支付宝沙箱操作
Django实现支付宝沙箱操作
Django实现支付宝沙箱操作
Django实现支付宝沙箱操作
Django实现支付宝沙箱操作
Django实现支付宝沙箱操作
Django实现支付宝沙箱操作
Django实现支付宝沙箱操作
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RLkaGka3-1602600315452)(C:%5CUsers%5CASUS%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5Cimage-20201013215646909.png#pic_center)]
)

4.将应用公钥复制到支付宝中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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.配置app中支付宝公钥 开发助手秘钥
  1. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hzEeNDd6-1602600230107)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20201013220610210.png)]
  2. 在Django的app中创建文件夹置放支付宝公钥[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bg9hMEFa-1602600230111)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20201013221108217.png)]
  3. 在Django的app中创建文件夹置放开放平台私钥[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0aGqpG4B-1602600230112)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20201013221548593.png)]

Django Models

# 支付状态表
class 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 Views配置

  1. 所需的包

    import uuid import redis from app01.views import login_serializer from alipay import AliPay, AliPayConfig
# 绝对路径打开文件  {}代表从这里往前 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()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TU8ck5hJ-1602600230116)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20201013222520219.png)]

alipay = AliPay( appid="2016102500759596", app_notify_url=None, # 默认回调url app_private_key_string=app_private_key_string, # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥, alipay_public_key_string=alipay_public_key_string, sign_type="RSA2", # RSA 或者 RSA2 debug=True, # 默认False config=AliPayConfig(timeout=15) # 可选, 请求超时时间 )

3.注释的代码可以去掉

# 支付 class 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() # # get到等于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 = Goods.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: print(ser.errors) # 主题 subject = "京东" # 电脑网站支付,需要跳转到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" # 可选, 不填则使用默认notify 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})

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m6WYKp5g-1602600230119)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20201013223018379.png)]

4.0

# 支付完回调地址 class CallBackAlipayView(APIView): def get(self, request): print(request.query_params) print("------------------------------") # 判断是否有数据 if request.query_params.get("sign"): # for i in request.query_params.get("out_trade_no"): # 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.save() else: print(ser.errors) return Response({'msg': 'OK', "data": request.query_params})

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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 } }) },
 

调用的页面

<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">
              <a href="login.html">登录</a>
              <span>|</span>
              <a href="register.html">注册</a>
            </div>
            <div class="user_link fl">
              <span>|</span>
              <a href="user_center_info.html">用户中心</a>
              <span>|</span>
              <a href="cart.html">我的购物车</a>
              <span>|</span>
              <a href="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>

      <div class="total_count">全部商品<em>{{cart.length}}</em>件</div>
      <ul class="cart_list_th clearfix">
        <li class="col01">商品名称</li>
        <li class="col03">商品价格</li>
        <li class="col04">数量</li>
        <li class="col05">小计</li>
        <li class="col06">操作</li>
      </ul>
      <ul class="cart_list_td clearfix" v-for="(sku,index) in cart">
        <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>
        <li class="col02">全选</li>
        <li class="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 {
                cart: [
                    
                ],
                check: [],
                username: "",
                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',
                    method: 'delete',
                    data: 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",
                    method: 'post',
                    data: data
                }).then(res => {
                    console.log(res.data)
                    if (res.data.code === 200) {

                        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',
                    method: 'post',
                    data: data
                }).then(res => {
                    console.log(res)
                    this.$router.go(0)

                })
            },
            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',
                    method: 'post',
                    data: data
                }).then(res => {
                    console.log(res)
                    this.$router.go(0)
                })
            },
            show() {
                axios({
                    url: 'http://127.0.0.1:8000/app02/showcart',
                    method: '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
                this.count2 = 0
                for (let i in this.cart) {
                    console.log(this.cart[i])
                    this.count2 += this.cart[i].price * this.cart[i].count
                }
            },


            //计算单选框
            checkbox(gid, count, price) {
                //第一次执行都为空 false
                console.log(this.check)
                if (this.check.includes(gid)) {
                    //    包含则说明已经选中 再次点击删除 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 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 scoped>

</style> 

本文地址:https://blog.csdn.net/weixin_45954124/article/details/109062783