Django se da cuenta de que el funcionamiento de la caja de arena de Alipay es demasiado fuerte.

Django implementa la operación de caja de arena de Alipay

El medio ambiente es el módulo requerido

  1. Django == 3.1.0
  2. python == 3.7.4
  3. python-alipay-sdk = 2.0.1

Necesario

  1. Descargar módulo python-alipay-sdk = 2.0.1
  2. Documente el SDK de Alipay Python no oficial: https://github.com/fzlee/alipay/blob/master/README.zh-hans.md#alipay.trade.page.pay

Configuración del entorno de zona de pruebas

 

  1. En la plataforma abierta Alipay ----> Centro de desarrolladores—> Servicio de desarrollo ----> Sandbox
  2. La generación y carga de la clave RSA2 se refieren a la dirección oficial: https://opendocs.alipay.com/open/291/105971
  3. Descargue la dirección de descarga del Asistente de desarrollo de plataforma abierta de Alipay https://opendocs.alipay.com/open/291/introduce para generar una clave secreta después de la descarga [Error en la transferencia de la imagen del enlace externo, el sitio de origen puede tener un mecanismo de cadena antirrobo, se recomienda guardar la imagen directamente Subir (img-iAJ4s57z-1602600230093) (C: \ Users \ ASUS \ AppData \ Roaming \ Typora \ typora-user-images \ image-20201013215751437.png)]















[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y subirla directamente (img-RLkaGka3-1602600315452) (C:% 5CUsers% 5CASUS% 5CAppData% 5CRoaming% 5CTypora% 5Ctypora-user-images% 5Cimage-20201013215646909.png # pic_center)]
)

4. Copie la clave pública de la aplicación en Alipay.

[Falló la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo anti-hotlink. Se recomienda guardar la imagen y subirla directamente (img-pm1umRDQ-1602600230099) (C: \ Users \ ASUS \ AppData \ Roaming \ Typora \ typora-user-images \ image-20201013220238000.png)]

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuelas. Se recomienda guardar la imagen y subirla directamente (img-xIM2Wwqr-1602600230101) (C: \ Users \ ASUS \ AppData \ Roaming \ Typora \ typora-user-images \ imagen-20201013220309533.png)]

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo anti-hotlinking. Se recomienda guardar la imagen y cargarla directamente (img-CZRSx4tY-1602600230104) (C: \ Users \ ASUS \ AppData \ Roaming \ Typora \ typora-user-images \ imagen-20201013220359867.png)]

5. Configure la clave secreta del asistente de desarrollo de clave pública de Alipay en la aplicación

  1. [Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo anti-hotlink. Se recomienda guardar la imagen y subirla directamente (img-hzEeNDd6-1602600230107) (C: \ Users \ ASUS \ AppData \ Roaming \ Typora \ typora-user-images \ image-20201013220610210.png)]
  2. Cree una carpeta en la aplicación Django y coloque la clave pública de Alipay (la transferencia de la imagen del enlace externo falló, el sitio de origen puede tener un mecanismo de cadena antirrobo, se recomienda guardar la imagen y cargarla directamente (img-Bg9hMEFa-1602600230111) (C: \ Users \ ASUS) \ AppData \ Roaming \ Typora \ typora-user-images \ image-20201013221108217.png)]
  3. Cree una carpeta en la aplicación Django y coloque la clave privada de la plataforma abierta. ASUS \ AppData \ Roaming \ Typora \ typora-user-images \ image-20201013221548593.png)]

Modelos de Django

# 支付 状态 表
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'

Configuración de vistas de Django

  1. 所需 的 包 importar uuid importar redis desde app01.views importar login_serializer desde alipay importar AliPay, AliPayConfig123
# 
Ruta absoluta para abrir el archivo {} significa avanzar desde aquí 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

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo anti-hotlinking. Se recomienda guardar la imagen y subirla directamente (img-TU8ck5hJ-1602600230116) (C: \ Users \ ASUS \ AppData \ Roaming \ Typora \ typora-user-images \ image-20201013222520219.png)]

  1.  
alipay = AliPay ( 
    appid = "2016102500759596", 
    app_notify_url = Ninguno, # predeterminado de devolución de llamada URL 
    app_private_key_string = app_private_key_string, 
    clave pública # Alipay, compruebe que el mensaje de retorno de Alipay se utiliza, no su propia clave pública, 
    alipay_public_key_string = alipay_public_key_string, 
    sign_type = "RSA2 ", # RSA o RSA2 
    debug = True, # Default False 
    config = AliPayConfig (timeout = 15) # Opcional, request timeout 
) 123456789

3. El código comentado se puede eliminar

# 
Clase de pago 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) 
        # El número de pedido uuid es único y único 
        out_trade_no = str (uuid.uuid4 ()) 
        # Importe del pedido inicial 
        total_amount = 0 
        user_info = login_serializer.loads (token) 
        user_id = user_info. get ('user_id') 
        # Determine si se usa para múltiples ID y divida por número 
        si goods_info.find (',')! = -1: 
            order_list = [] 
            for i in goods_info.split (','):
                print (i) 
            # lista de adición por lotes 
                # Cycle output id
                # # Obtener el número de artículos en el carrito de compras 
                # Goods_count = r3.hget (user_id, i) .decode () 
                # # Obtener el artículo igual a i 
                # goods_obj = Goods.objects.get (pk = i) 
                # # Calcular el precio total 
                # total_amount + = int (Goods_obj.price) * int (Goods_count) \ 

                # Tipo de adición de lista 
                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) 
            # cantidad_total + = int (Goods_obj.price) * int (Goods_count) 
            # print (total_amount) 

            # 单个 添加
            ser = OrderModelSer (data = { 
                "out_trade_no": out_trade_no, 
                "Goods": Goods_info, 
                "usuario": user_id, 
                "Goods_num": count, 
                "status": 1 
            si ser.is_valid (): 
                ser.guardar () 
            más: 
                print (ser.errors) 

        # Subject 
        subject = "京东" 

        # Pago del sitio web de la computadora, debes ir a 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" # Elija, si no completa, use la URL de notificación predeterminada 
        ) 
        # datos cosidos 
        # print (order_string) 
        pay_url = 'https: //openapi.alipaydev.com/gateway.do?'+ order_string 
        # Ruta con salto de parámetro
        # print (pay_url) 
        return Response ({'pay_url': pay_url, 'msg': 'OK', "código": 200}) 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455566575675

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuelas. Se recomienda guardar la imagen y subirla directamente (img-m6WYKp5g-1602600230119) (C: \ Users \ ASUS \ AppData \ Roaming \ Typora \ typora-user-images \ image-20201013223018379.png)]

4.0

# Dirección de devolución de llamada después de la 
clase de pago CallBackAlipayView (APIView): 

    def get (self, request): 
        print (request.query_params) 
        print ("---------------------- -------- ") 
        # Determinar si hay datos 
        si request.query_params.get (" sign "): 
            # for i in request.query_params.get (" out_trade_no "): 
            # print (request.query_params.get ("out_trade_no")) 
            # Obtener el número de pedido 
            queryset = Order.objects.get (out_trade_no = request.query_params.get ("out_trade_no")) 

            # Modificar el estado del pedido a la modificación parcial comprada 
            ser = OrderModelSer (instance = queryset, data = {"estado": 2}, parcial = Verdadero) 
            si ser.is_valid (): 
                ser.salvar()
            else:
                print (ser.errors) 

        return Response ({'msg': 'OK', "data": request.query_params}) 1234567891011121314151617181920

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo anti-hotlinking. Se recomienda guardar la imagen y subirla directamente (img-AFbrRopL-1602600230122) (C: \ Users \ ASUS \ AppData \ Roaming \ Typora \ typora-user-images \ image-20201013223126443.png)]

Interfaz de llamada

addcart () { 
    dejar datos = nuevo 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 ", 
        método: 'publicar', 
        datos: datos 
    }). Luego (res => { 
        console.log (res.data) 
        if (res.data.code === 200) { 

            window.location.href = res.data.pay_url 
        } 
    }) 
}, 12345678910111213141516
1

Página llamada

<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 = "搜索 商品 ">form method = "get" action = "/ search.html" class = "search_con fr mt40"> 
          <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, índice) en el carrito "> 
        <li class = "col01"> <input type = "checkbox" name = "" v-model = "check": value = "sku.id" 
                                 @ click = "casilla de verificación (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> 
        <li class = "col01"> <input type = "checkbox" @ click = "check_count" v-model = "isChecked"> </li> 
        <li class = "col02"> 全选 </li>

      <ul class = "asentamientos"> 
        <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> 
    importar axios de 'axios' 
    importar fooder de '../components/Fooder' 

    exportar predeterminado { 
        nombre: "Carrito"
        datos () { 
            devolver { 
                carrito: [ 
                    
                ], 
                comprobar: [], 
                nombre de usuario: "",
                total_selected_amount: "", 
                total_selected_count: "",
                on_selected_all: "", 
                selected_all: "", 
                count2: 0, 
                isChecked: false, 


            } 
        }, 
        componentes: { 
            'fooder': fooder 
        }, 
        métodos: { 
            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', 
                }). luego (res => {
                    datos: datos
                    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 ", 
                    método: 'publicar', 
                    datos: datos 
                }). Luego (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) { 
                dejar datos = new FormData (); 
                data.append ("token", sessionStorage.getItem ("token")) 
                data.append ("Goods_id", Goods_id) 

                axios ({ 
                    url: 'http://127.0.0.1:8000/app02/addcart', 
                    método: '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', 
                    método: 'post', 
                    data: data 
                }). luego (res => { 
                    console.log (res) 
                    this. $ router.go (0) 
                }) 
            }, 
            show () {  
                axios ({
                    url: 'http://127.0.0.1: 8000 / app02 / showcart ', 
                    método:' get ', 
                    params: {"token": sessionStorage.getItem ("token ")} 
                }). luego (res => { 
                    //127.0.0.1:8000 
            / app02 / showcart 
                    console.log (res) this.cart = res.data.data 
                }) 
            }, // Seleccionar todo y llamar al total Price 

            check_count () { 
                // El valor predeterminado es falso 
                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 () 
                    }) 

                } 
            }, 
            // Calcular el precio total 
            count () { 
                // let count = 0 
                if (this.check.includes (gid)) {
                this.count2 = 0 
                for (let i in this.cart) { 
                    console.log (this.cart [i]) 
                    this.count2 + = this.cart [i] .price * this.cart [i] .count 
                } 
            } , 


            // Calcular la 
            casilla de verificación del botón de radio (gid, count, price) { 
                // La primera ejecución está vacía false 
                console.log (this.check) 
                    // Si contiene, significa que ha sido seleccionado y haz clic nuevamente para eliminar false y restar el correspondiente Price 
                    this.count2 - = count * price 
                    this.check.splice (this.check.indexOf (gid), 1) 


                } else { 
                    // Empujar significa que agregar se convierte en realidad 
                    this.check.push [gid]
                    // Calcula el precio total, selecciona y agrega 
                    this.count2 + = count * price 
                } 
            }, 
        }, 
        created () { 
            this.show () 
        } 
    } 
</script> 

<style scoped> 

</style> haz 
clic para eliminar falso y restar Ir al precio correspondiente 
                    this.count2 - = count * price 
                    this.check.splice (this.check.indexOf (gid), 1) 
            }, 
        },

 
                } else {
                    // Empujar significa que agregar se convierte en realidad 
                    this.check.push [gid] 
                    // Calcule el precio total, seleccione y agregue 
                    this.count2 + = count * price 
                }
        created () { 
            this.show () 
        } 
    } 
</script> 

<estilo con alcance> 

</style>

PD: Si necesita materiales de aprendizaje de Python, puede hacer clic en el enlace de abajo para obtenerlo usted mismo.

El código completo se puede obtener haciendo clic en el enlace de abajo ~

Materiales de aprendizaje gratuitos de Python y respuestas de comunicación grupal Haga clic para unirse

 

Supongo que te gusta

Origin blog.csdn.net/weixin_43881394/article/details/109096181
Recomendado
Clasificación