vue支付封装

本文介绍了一个支付方式选择组件的设计与实现细节,包括不同支付方式的处理流程、支付状态监测及弹窗交互等内容。
<template>
  <div>
    <!-- 选择支付方式 -->
    <el-dialog
      title="选择支付方式"
      :visible.sync="isPaylist"
      :before-close="isPayhandleClose"
      custom-class="paylist"
    >
      <div v-loading="isPaylistLoading">
        <!-- <div @click="qq">qqqqq</div>
        <canvas id="QRCode"></canvas> -->
        <ul class="paytype">
          <li
            class="payitem"
            :class="isselect == 4 ? 'active' : ''"
            @click="isselect = 4"
          >
            <div class="paylabel">
              <svg class="icon" aria-hidden="true">
                <use xlink:href="#icon-xianjin" />
              </svg>
              <span class="tit">现金支付</span>
            </div>

            <div class="paysanjiao" v-if="isselect == 4"></div>
            <i class="iconfont icon-tubiao--" v-if="isselect == 4"></i>
          </li>
          <li
            class="payitem"
            :class="isselect == 1 ? 'active' : ''"
            @click="isselect = 1"
            v-if="paylist.wx == 1 && money"
          >
            <div class="paylabel">
              <svg class="icon" aria-hidden="true">
                <use xlink:href="#icon-weixinzhifu" />
              </svg>
              <span class="tit">微信支付</span>
            </div>

            <div class="paysanjiao" v-if="isselect == 1"></div>
            <i class="iconfont icon-tubiao--" v-if="isselect == 1"></i>
          </li>
          <li
            class="payitem"
            :class="isselect == 2 ? 'active' : ''"
            @click="isselect = 2"
            v-if="paylist.ali == 1 && money"
          >
            <div class="paylabel">
              <svg class="icon" aria-hidden="true">
                <use xlink:href="#icon-zhifubaocai" />
              </svg>
              <span class="tit">支付宝支付</span>
            </div>

            <div class="paysanjiao" v-if="isselect == 2"></div>
            <i class="iconfont icon-tubiao--" v-if="isselect == 2"></i>
          </li>
          <li
            class="payitem"
            :class="isselect == 5 ? 'active' : ''"
            @click="isselect = 5"
            v-if="paylist.zs == 1 && money"
          >
            <div class="paylabel">
              <svg class="icon" aria-hidden="true">
                <use xlink:href="#icon-zhaoshangyinhang" />
              </svg>
              <div class="juhe">
                <div class="tits">聚合扫码支付</div>
                <div class="tip">(微信、支付宝都可扫)</div>
              </div>
            </div>

            <div class="paysanjiao" v-if="isselect == 5"></div>
            <i class="iconfont icon-tubiao--" v-if="isselect == 5"></i>
          </li>
        </ul>
        <div class="paybtn">
          <el-button @click="isPayhandleClose">取消</el-button>
          <el-button class="paydone" type="primary" @click="postselect"
            >确认</el-button
          >
        </div>
      </div>
    </el-dialog>
    <!-- 选择支付方式 -->
    <!-- 现金支付 -->
    <el-dialog
      :visible.sync="selectcash"
      width="600px"
      :before-close="handleClose"
      custom-class="cashpay"
    >
      <h5>
        <svg class="icon" aria-hidden="true">
          <use xlink:href="#icon-xianjin" />
        </svg>
        <span>现金支付</span>
      </h5>
      <div class="cashcontent">
        <div class="cashneed">需支付</div>
        <div class="cashnum">{{ Number(money).toFixed(2) }}</div>
      </div>
      <div class="cashtip">
        请与学员当面进行交易。
        <br />交易完成后,请在“财务中心->收款记录”中,点击“确认收款”按钮。帮学员完成支付。
      </div>
      <div class="cashbtn">
        <el-button @click="selectcash = false">取消</el-button>
        <el-button type="primary" @click="cashdone">确认</el-button>
        <el-button
          @click="
            selectcash = false;
            isPaylist = true;
          "
          >上一步</el-button
        >
      </div>
    </el-dialog>
    <!-- 现金支付 -->
    <!-- 支付宝支付中 -->
    <el-dialog
      :visible.sync="zhifuzhong"
      width="600px"
      :before-close="handleClose"
      custom-class="cashpay online"
    >
      <h5>
        <svg class="icon" aria-hidden="true">
          <use xlink:href="#icon-zhifubaocai" />
        </svg>
        <span>支付宝支付</span>
      </h5>
      <div class="cashcontent">
        <div class="cashneed">需支付</div>
        <div class="cashnum">{{ Number(money).toFixed(2) }}</div>
      </div>
      <div class="zhifuziti">
        <p class="blue">请务必确认您在支付宝网站上完成了该笔支付。</p>
        <p>如果 10 秒后没有自动返回 ,请点击“返回商户”按钮使交易继续。</p>

        <p class="gray">
          该过程可能会长达 60
          秒。为了避免购买失败,在交易结束前请不要关闭支付宝窗口。
        </p>
      </div>
      <div class="cashbtnzf">
        <el-button type="senior">支付中,请稍等...</el-button>
      </div>
    </el-dialog>
    <!-- 支付宝支付中 -->
    <!-- 微信支付弹窗 -->
    <el-dialog
      :visible.sync="selectweixin"
      width="600px"
      :before-close="handleClose"
      custom-class="cashpay online"
    >
      <div v-loading="onlineloading">
        <h5>
          <svg class="icon" aria-hidden="true">
            <use xlink:href="#icon-weixinzhifu" />
          </svg>
          <span>微信支付</span>
        </h5>
        <div class="cashcontent">
          <div class="cashneed">需支付</div>
          <div class="cashnum">{{ Number(money).toFixed(2) }}</div>
        </div>
        <div class="cashqrcode">
          <div class="qritem">
            <canvas id="QRCode"></canvas>
          </div>
          <div class="qrfont">请使用微信扫描二维码进行支付</div>
        </div>
        <div class="cashbtn">
          <el-button type="senior" @click="(selectweixin = false), dingdanyz()"
            >支付成功</el-button
          >
          <el-button @click="selectweixin = false">取消支付</el-button>
        </div>
      </div>
    </el-dialog>
    <!-- 微信支付弹窗 -->
    <!-- 聚合支付弹窗 -->
    <el-dialog
      :visible.sync="selectjuhe"
      width="600px"
      :before-close="handleClose"
      custom-class="cashpay online"
    >
      <div v-loading="onlinejhloading">
        <h5>
          <svg class="icon" aria-hidden="true">
            <use xlink:href="#icon-zhaoshangyinhang" />
          </svg>
          <span>聚合扫码支付</span>
        </h5>
        <div class="cashcontent">
          <div class="cashneed">需支付</div>
          <div class="cashnum">{{ Number(money).toFixed(2) }}</div>
        </div>
        <div class="cashqrcode">
          <div class="qritem">
            <canvas id="QRCodejh"></canvas>
          </div>
          <div class="qrfont">请使用微信或支付宝扫描二维码进行支付</div>
        </div>
        <div class="cashbtn">
          <el-button type="senior" @click="(selectweixin = false), dingdanyz()"
            >支付成功</el-button
          >
          <el-button @click="selectweixin = false">取消支付</el-button>
        </div>
      </div>
    </el-dialog>
    <!-- 聚合支付弹窗 -->
  </div>
</template>

<script>
import QRCode from "qrcode"; //调用支付二维码
export default {
  data() {
    return {
      isPaylistLoading: true, //支付方式显隐弹窗loading
      paylist: {}, //支付方式列表
      isselect: "", //选中的支付方式
      selectcash: false, //选择现金
      zhifuzhong: false, //支付宝支付中
      selectweixin: false, //微信支付
      onlineloading: true, //微信支付loading
      gunior_id: "", //校区id
      orgid: "", //机构id
      onlinejhloading: true, //聚合显隐loading
      selectjuhe: false,
      QRCodejhMsg: "",
      QRCodeMsg: "",
      settime: null, //查询订单定时器
    };
  },
  props: {
    // 订单号
    isPaylist: {
      type: Boolean,
      default: false,
    },
    // 订单号
    code: {
      type: String,
      default: "",
    },
    // 支付金额
    money: {
      type: Number,
      default: 0,
    },
    // 支付后跳转url
    url: {
      type: String,
      default: "",
    },
    // 商品描述
    desc: {
      type: String,
      default: "补课订单",
    },
    // 商户保留域

    orderType: {
      type: String,
      default: "make_up",
    },
    // 1=全款支付 2=订金支付 3=尾款支付
    payment: {
      type: String,
      default: "1",
    },
    studentId: {
      type: String,
      default: "",
    },
  },
  watch: {
    isPaylist(val) {
      this.isPaylist = val;
    },
    // 通过微信监听获取数据
    QRCodeMsg(val) {
      // 获取页面的canvas
      var msg = document.getElementById("QRCode");
      // 将获取到的数据(val)画到msg(canvas)上
      QRCode.toCanvas(msg, val, function (error) {
        console.log(error);
      });
    },
    // 通过聚合监听获取数据
    QRCodejhMsg(val) {
      // 获取页面的canvas
      var msg = document.getElementById("QRCodejh");
      // 将获取到的数据(val)画到msg(canvas)上
      QRCode.toCanvas(msg, val, function (error) {
        //console.log(error);
      });
    },
  },
  destroyed() {
    clearInterval(this.settime);
  },
  methods: {
    // 支付方式关闭
    isPayhandleClose() {
      this.$emit("isPayhandleClose", false);
    },
    // 支付方式缺
    postselect() {
      this.$emit("getselect", this.isselect);
    },
    // 选择的支付方式显示
    paytypexs() {
      if (this.isselect == 4) {
        //现金支付
        this.selectcash = true;
      } else if (this.isselect == 1) {
        //微信支付生成二维码
        this.selectweixin = true;
        this.onlineloading = true;
        axios
          .post("/api/makeup/wechat", {
            code: this.code,
            gunior_id: this.gunior_id,
            orgid: this.orgid,
            payment: this.payment,
            student_id: this.studentId,
          })
          .then((res) => {
            if (res.data.code == 1) {
              this.chaxun();
              this.onlineloading = false;
              this.QRCodeMsg = res.data.data;

              this.onlineloading = false;
            } else {
              this.selectweixin = false;
              this.onlineloading = false;
              this.$message({
                showClose: true,
                message: res.data.msg,
                type: "error",
              });
            }
          })
          .catch((err) => {
            console.log(err);
          });
      } else if (this.isselect == 2) {
        this.zhifuzhong = true;
        //支付宝跳页面支付
        window.open(
          "/api/makeup/ali?code=" +
            this.code +
            "&gunior_id=" +
            this.gunior_id +
            "&orgid=" +
            this.orgid +
            "&student_id=" +
            this.studentId +
            "&payment=" +
            this.payment
        );
        this.chaxun();
      } else if (this.isselect == 5) {
        // 聚合支付
        this.selectjuhe = true;
        this.onlinejhloading = true;
        axios
          .post("/api/zsPay/cmbPay", {
            order_id: this.code,
            junior_id: this.gunior_id,
            org_id: this.orgid,
            desc: this.desc,
            money: this.money,
            order_type: this.orderType,
            payment: this.payment,
          })
          .then((res) => {
            if (res.data.errCode == 200) {
              this.chaxun();
              this.QRCodejhMsg = res.data.data;
              this.onlinejhloading = false;
            } else {
              this.selectjuhe = false;
              this.onlinejhloading = false;
              this.$message({
                showClose: true,
                message: res.data.respMsg,
                type: "error",
              });
            }
          })
          .catch((err) => {
            console.log(err);
          });
      }
    },
    // 判断支付方式的显隐
    payType() {
      this.isPaylistLoading = true;
      axios
        .get("api/common/payment")
        .then((res) => {
          if (res.data.code == 1) {
            this.paylist = res.data.data;
            setTimeout(() => {
              var len = document.querySelectorAll(".payitem").length;
              console.log(len, "len");
              var wk = document.querySelector(".paytype");
              if (len == 4 || len == 2) {
                wk.style.width = "526px";
              } else if (len == 3) {
                wk.style.width = "789px";
              } else if (len == 1) {
                wk.style.width = "258px";
              }
              console.log(wk.style.width);
              this.isPaylistLoading = false;
            }, 500);
          } else {
            this.$message({
              showClose: true,
              message: res.data.msg,
              type: "error",
            });
            this.isPaylistLoading = false;
          }
        })
        .catch((err) => {
          console.log(err);
          this.isPaylistLoading = false;
        });
    },
    //现金支付确认
    cashdone() {
      axios
        .post("api/makeup/cash", {
          code: this.code,
          gunior_id: this.gunior_id,
          orgid: this.orgid,
          payment: this.payment,
        })
        .then((res) => {
          if (res.data.code == 1) {
            this.selectcash = false;
            this.$message({
              showClose: true,
              message: res.data.msg,
              type: "success",
            });
            if (this.url) {
              this.$router.push(this.url);
            } else {
              this.$router.go(0);
            }
            this.loading = true;
          } else {
            this.$message({
              showClose: true,
              message: res.data.msg,
              type: "error",
            });
          }
        })
        .catch((err) => {
          console.log(err);
        });
    },
    dingdanyz() {
      if (this.isselect == 5) {
        axios
          .post("/api/zsPay/paySelect", {
            junior_id: this.gunior_id,
            org_id: this.orgid,
            order_id: this.code,
          })
          .then((res) => {
            if (res.data.errCode == 200) {
              clearInterval(this.settime);
              this.$message({
                showClose: true,
                message: res.data.respMsg,
                type: "success",
              });
              if (this.url) {
                this.$router.push(this.url);
              } else {
                this.$router.go(0);
              }
            } else {
              this.isPaylist = false;
              this.isPaylistLoading = false;
              this.selectcash = false;
              this.selectweixin = false;
              this.selectsuccess = false;
              this.onlineloading = false;
              this.zhifuzhong = false;
              this.$message({
                showClose: true,
                message: res.data.respMsg,
                type: "error",
              });
            }
          })
          .catch((err) => {
            console.log(err);
          });
      } else {
        axios
          .post("/api/edu/check", {
            type: 1,
            code: this.code,
          })
          .then((res) => {
            if (res.data.code == 1) {
              clearInterval(this.settime);
              this.$message({
                showClose: true,
                message: res.data.msg,
                type: "success",
              });
              if (this.url) {
                this.$router.push(this.url);
              } else {
                this.$router.go(0);
              }
            } else {
              this.isPaylist = false;
              this.isPaylistLoading = false;
              this.selectcash = false;
              this.selectweixin = false;
              this.selectsuccess = false;
              this.onlineloading = false;
              this.zhifuzhong = false;
              this.$message({
                showClose: true,
                message: res.data.msg,
                type: "error",
              });
            }
          })
          .catch((err) => {
            console.log(err);
          });
      }
    },
    //查询是否支付成功(10s)
    chaxun() {
      this.settime = setInterval(() => {
        if (this.isselect == 5) {
          axios
            .post("/api/zsPay/paySelect", {
              junior_id: this.gunior_id,
              org_id: this.orgid,
              order_id: this.code,
            })
            .then((res) => {
              if (res.data.errCode == 200) {
                this.$message({
                  showClose: true,
                  message: "支付成功",
                  type: "success",
                });
                clearInterval(this.settime);
                if (this.url) {
                  this.$router.push(this.url);
                } else {
                  this.$router.go(0);
                }
              } else {
                this.isPaylist = false;
                this.isPaylistLoading = false;
                this.selectcash = false;
                this.selectweixin = false;
                this.selectsuccess = false;
                this.onlineloading = false;
                this.zhifuzhong = false;
                this.$message({
                  showClose: true,
                  message: res.data.respMsg,
                  type: "error",
                });
              }
            })
            .catch((err) => {
              console.log(err);
            });
        } else {
          axios
            .post("/api/edu/check", {
              type: 1,
              code: this.code,
            })
            .then((res) => {
              if (res.data.code == 1) {
                clearInterval(this.settime);
                this.$message({
                  showClose: true,
                  message: res.data.msg,
                  type: "success",
                });
                if (this.url) {
                  this.$router.push(this.url);
                } else {
                  this.$router.go(0);
                }
              } else {
                this.isPaylist = false;
                this.isPaylistLoading = false;
                this.selectcash = false;
                this.selectweixin = false;
                this.selectsuccess = false;
                this.onlineloading = false;
                this.zhifuzhong = false;
                this.$message({
                  showClose: true,
                  message: res.data.msg,
                  type: "error",
                });
              }
            })
            .catch((err) => {
              console.log(err);
            });
        }
      }, 10000);
    },
  },
  mounted() {
    this.payType();
    this.gunior_id = JSON.parse(
      window.localStorage.getItem("userInfo")
    ).gunior_id;
    this.orgid = JSON.parse(window.localStorage.getItem("userInfo")).orgid;
  },
  computed: {},
};
</script>
<style>
.paylist.el-dialog {
  width: fit-content;
}
</style>
<style scoped lang="scss">
/* 选择支付方式弹窗 */
.paylist {
  .paybtn {
    width: 100%;
    margin-top: 30px;
    clear: both;
    overflow: hidden;
    button {
      float: right;
    }
    .paydone {
      margin-right: 10px;
    }
  }
  .paytype {
    width: 789px;
    margin-top: 25px;
    flex-wrap: wrap;
    display: flex;
    li {
      width: 253px;
      height: 253px;
      cursor: pointer;
      margin: 5px;
      background-color: #f6f8f9;
      position: relative;
      border: solid 2px #f6f8f9;
      padding: 20px 10px;
      display: flex;
      align-items: center;
      justify-content: center;
      .paysanjiao {
        width: 0;
        height: 0;
        border-top: 33px solid #40c4f4;
        border-left: 65px solid transparent;
        position: absolute;
        right: 0;
        top: 0;
        color: #fff;
      }
      i {
        font-size: 21px;
        font-weight: 600;
        transform: rotate(17deg);
        position: absolute;
        right: 7px;
        top: -2px;
        color: #fff;
      }
      .paylabel {
        font-size: 24px;
        width: 100%;
        height: 63px;
        display: flex;
        .tit {
          line-height: 63px;
        }
        svg {
          margin-right: 6px;
          width: 76px;
          height: 63px;
        }
        .juhe {
          padding-top: 9px;
          .tits {
            font-size: 20px;
          }
          .tip {
            font-size: 12px;
          }
        }
      }
    }
    .active {
      border: solid 2px #40c4f4;
    }
  }
}
/* 现金支付弹窗 */
.cashpay {
  h5 {
    font-weight: normal;
    font-size: 16px;
    svg {
      margin-right: 12px;
    }
  }
  .cashcontent {
    width: 100%;
    height: 130px;
    margin-top: 23px;
    background-color: #f6f8f9;
    text-align: center;
    .cashneed {
      float: left;
      font-size: 16px;
      color: #666;
      line-height: 140px;
      margin-right: 8px;
      margin-left: 110px;
    }
    .cashnum {
      float: left;
      font-size: 36px;
      color: #333;
      line-height: 130px;
    }
  }
  .cashtip {
    color: #666;
    margin-top: 15px;
  }
  .cashbtn {
    margin-top: 23px;
    overflow: hidden;
    button {
      margin-left: 10px;
      float: right;
    }
  }
}
// 支付宝支付
.online {
  height: 377px;
  .cashcontent {
    height: 86px;
    .cashneed {
      line-height: 94px !important;
    }
    .cashnum {
      line-height: 86px !important;
    }
  }
  .cashqrcode {
    margin-top: 25px;
    padding: 0 30px;
    display: flex;
    justify-content: space-around;
    align-items: center;
    .qritem {
      width: 120px;
      height: 120px;
      canvas {
        width: 100%;
        height: 100%;
      }
    }
    .qrfont {
      width: 150px;
    }
  }
  .cashbtnzf {
    text-align: right;
    margin-top: 20px;
  }
  .zhifuziti {
    text-align: left;
    margin-top: 10px;
    line-height: 20px;
    .blue {
      margin-top: 26px;
    }
    .gray {
      margin-top: 26px;
    }
  }
}
</style>
import Pay from "../../../components/pay.vue";
components: { Pay },
<Pay
      ref="paytype"
      :code="detaildata.code"
      :money="money"
      :isPaylist="isPaylist"
      :payment="payment"
      :desc="desc"
      :orderType="'shop'"
      :studentId="studentId"
      :url="url"
      v-if="isPay"
      @getselect="getselect"
      @isPayhandleClose="isPayhandleClose"
    ></Pay>

code:订单编号;
money:支付的金额;
isPaylist:支付方式列表弹窗情况
payment:金额状态 1=全款支付 2=订金支付 3=尾款支付
desc:商品描述
orderType:make_up–补课订单shop–商城订单change_class–转班change_lesson–转课resume_lesson–退课
studentId:学员id
url成功后跳转链接

isPay: false, //支付组件显隐
isPaylist: false,//支付组件中支付列表显示
//显示
showModal() {
      this.isPay = true;
      this.isPaylist = true;
    },
 //关闭支付方式弹框
    isPayhandleClose(val) {
      this.isPaylist = false;
    },
 // 选择支付方式切换弹窗,要是没有code先执行生成code方法
    getselect(val) {
      this.isselect = val;
      this.isPaylist = false;
      this.$refs.paytype.paytypexs();
    },
	//支付宝App支付
			getAppZfbPay(orderInfo) {
				console.log(orderInfo, 'orderInfo')
				let _this = this
				uni.requestPayment({
					provider: 'alipay',
					orderInfo: orderInfo.orderStr, //微信、支付宝订单数据 【注意微信的订单信息,键值应该全部是小写,不能采用驼峰命名】
					success: function(res) {
						uni.showToast({
							title: "支付成功",
							icon: "success"
						})
						_this.show = false
						_this.tosuss()
					},
					fail: function(err) {
						console.log(err)
						uni.showToast({
							title: "支付失败",
							icon: "none",
						})
						setTimeout(() => {
							_this.torest()
						}, 1500)
					}
				});
			},
			//小程序微信支付
			getWxPay(orderInfo) {
				var that = this
				uni.requestPayment({
					provider: 'wxpay',
					timeStamp: orderInfo.timeStamp,
					nonceStr: orderInfo.nonceStr,
					package: orderInfo.package,
					signType: orderInfo.signType,
					paySign: orderInfo.paySign,
					success: function(res) {
						uni.showToast({
							title: "支付成功",
							icon: "success"
						})
						setTimeout(() => {
							that.tosuss()
						}, 1500)
					},
					fail: function(err) {
						that.torest()
						uni.showToast({
							title: "支付失败",
							icon: "none",
						})
					}
				});
			},
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值