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. 下载支付宝开放平台开发助手
    1. 下载地址https://opendocs.alipay.com/open/291/introduce
    2. 下载后生成秘钥
    3. Django实现支付宝沙箱操作_第1张图片
4.将应用公钥复制到支付宝中

Django实现支付宝沙箱操作_第2张图片
Django实现支付宝沙箱操作_第3张图片
Django实现支付宝沙箱操作_第4张图片

5.配置app中支付宝公钥 开发助手秘钥

Django实现支付宝沙箱操作_第5张图片
Django实现支付宝沙箱操作_第6张图片

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()

Django实现支付宝沙箱操作_第7张图片

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

4.0支付完回调地址Django实现支付宝沙箱操作_第8张图片

# 支付完回调地址
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})

5.0路由配置
Django实现支付宝沙箱操作_第9张图片

调用接口

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>

你可能感兴趣的:(支付宝,python,mysql,javascript,vue.js,django)