Django实现支付宝沙箱操作,太强了呀!

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. 下载支付宝开放平台开发助手下载地址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.将应用公钥复制到支付宝中

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

  1.  
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)  # 可选, 请求超时时间
)123456789

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})12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576

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

PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取

完整代码可以点击下方链接获取~

python免费学习资料以及群交流解答点击即可加入

猜你喜欢

转载自blog.csdn.net/weixin_43881394/article/details/109096181