在 UniApp 中使用Mixins混合方法实现微信支付与支付宝支付

在 UniApp 中使用Mixins混合方法实现微信支付与支付宝支付

目录

在 UniApp 中使用Mixins混合方法实现微信支付与支付宝支付

前言

UniAp 中集成支付功能时,我们经常需要根据不同的支付方式(如微信支付、支付宝支付)进行不同的处理。为了避免代码冗余和提升代码的可维护性,可以使用 VueMixins 技术 将支付逻辑提取到单独的混合文件中,在需要的地方复用。这不仅提高了代码的可重用性,还能够帮助我们更加清晰地组织代码结构。本文将详细解释如何在 UniApp 中使用 Vue Mixins 技术来处理微信支付和支付宝支付的逻辑,并结合实际代码进行说明。

项目概述

本项目展示了如何在 UniApp 中集成 微信支付 和 支付宝支付。根据不同的平台和支付方式,代码会根据选择的支付渠道来进行相应的请求和处理。

功能概述:

根据支付方式(支付宝或微信支付)展示不同的支付流程。
支付过程中包括获取订单信息、请求支付、支付成功或失败的回调处理。

代码解析

data() 数据定义

data 中定义了以下几个属性:

  • provider: 支付方式,默认设置为 'alipay',即初始使用支付宝支付。根据需求,可以动态切换为微信支付。
  • loading: 用于标识支付是否正在进行中。避免用户在支付过程中多次点击支付按钮。
  • data: 存储请求支付接口所需要的订单信息。
data() {
  return {
    provider: 'alipay', // 支付方式, 即提供商
    loading: false, // 是否提交中
    data: {}, // 订单信息服务接口请求参数
  }
}

onLoad() 页面加载时的支付方式选择

onLoad 方法中,根据平台的不同,设置支付方式。在微信小程序(MP-WEIXIN)中,支付方式会自动切换为微信支付(wxpay)

onLoad(option) {
  // #ifdef MP-WEIXIN
  // 微信小程序选中微信支付
  this.provider = 'wxpay'
  // #endif
}

payChange() 支付方式选择

用户可以通过界面选择支付方式(支付宝或微信支付)。payChange 方法会根据用户的选择更新 provider 的值。

payChange(e) {
  this.provider = e.detail.value
}

payHandler() 支付处理逻辑

payHandler 方法用于执行支付逻辑:

  • 首先,设置 loadingtrue,表示支付操作正在进行中。
  • 获取订单信息(通过 getOrderInfo() 方法)。
  • 根据支付渠道(provider)调用 uni.requestPayment(),这是 UniApp 提供的支付接口,用于发起支付请求。
  • 支付成功或失败时,分别触发 successfail 回调。
  • 完成支付后,返回订单页面并显示支付成功的提示。
async payHandler() {
  // 支付中
  this.loading = true
  // #ifdef APP-PLUS
  let orderInfo = await this.getOrderInfo();
  if (!orderInfo) {
    uni.showModal({
      content: '获取支付信息失败',
      showCancel: false
    })
    return
  }
  uni.requestPayment({
    provider: this.provider,
    orderInfo: orderInfo,
    success: (e) => {
      console.log("success", e);
      uni.showToast({
        title: "支付成功!"
      })
      this.navTo('/pages/order/order')
    },
    fail: (e) => {
      console.log("fail", e);
      uni.showModal({
        content: "支付失败,请重试。",
        showCancel: false
      })
    },
    complete: () => {
      this.loading = false;
    }
  })
  // #endif
}

getOrderInfo() 获取订单信息

getOrderInfo() 方法用于从后端获取支付订单信息:

  • 如果 openid 存在(即微信小程序支付),则直接返回模拟的订单信息。
  • 否则,根据选择的支付方式(支付宝或微信支付),调用对应的 API获取订单信息。
  • 如果成功返回订单信息,调用 resolve(),否则返回错误。
getOrderInfo(openid) {
  return new Promise(async (resolve, reject) => {
    if (openid) {
      let orderInfo = {
        "timeStamp": "1414561699",
        "nonceStr": "5K8264ILTKCH16CQ2502SI8ZNMTM67VS",
        "package": "prepay_id=wx201410272009395522657a690389285100", 
        "paySign": "oR9d8PuhnIc+YZ8cBHFCwfgpaK9gd7vaRvkYD7rthRAZ"
      }
      resolve(orderInfo)
      return
    }
    let res = null
    if (this.provider === 'alipay') {
      res = await api.getOrderInfoAlipay(this.data)
    } else if (this.provider === 'wxpay') {
      res = await api.getOrderInfoWxpay(this.data)
    }
    if (res && res.code === 20000) {
      resolve(res.data)
    } else {
      reject(new Error('获取支付信息失败' + res.message))
    }
  })
}

wxPayHandler() 微信支付流程

wxPayHandler() 方法主要用于微信小程序支付:

  • 获取用户的 openid,如果没有存储在本地,调用loginWeixinMp()方法进行微信登录。
  • 根据 openid 获取订单信息。
  • 调用 uni.requestPayment() 发起微信支付请求。
  • 支付完成后处理结果,展示支付成功或失败的提示。
async wxPayHandler() {
  this.loading = true
  let openid = uni.getStorageSync('openid')
  if (!openid) {
    try {
      openid = await this.loginWeixinMp()
    } catch (e) {
      console.error(e)
    }
    if (!openid) {
      uni.showModal({
        content: '获取openid失败',
        showCancel: false
      })
      this.loading = false
      return
    }
  }
  let orderInfo = await this.getOrderInfo(openid)
  uni.requestPayment({
    ...orderInfo,
    success: (res) => {
      uni.showToast({
        title: "支付成功!"
      })
    },
    fail: (res) => {
      uni.showModal({
        content: "支付失败, 原因: " + res.errMsg,
        showCancel: false
      })
    },
    complete: () => {
      this.loading = false;
    }
  })
}

loginWeixinMp() 微信小程序登录获取 openid

oginWeixinMp() 方法用于在微信小程序中获取 openid

  • 使用 uni.login() 获取微信登录的 code
  • 通过后端接口请求获取 openid 并存储在本地。
loginWeixinMp() {
  return new Promise((resolve, reject) => {
    uni.login({
      provider: 'weixin',
      success: (res) => {
        const code = res.code
        let openid = 'xx' // 获取openid的请求
        uni.setStorageSync('openid', openid)
        resolve(openid)
      },
      fail(err) {
        reject(err)
      }
    })
  })
}

微信支付与支付宝支付步骤总结

微信支付:

  1. 获取用户的 openid(用于标识用户身份)。
  2. 通过 openid 向后端请求订单信息。
  3. 调用 uni.requestPayment() 发起支付请求。
  4. 支付完成后,展示支付结果并处理回调。

支付宝支付:

  1. 选择支付宝作为支付渠道。
  2. 向后端请求订单信息。
  3. 调用 uni.requestPayment() 发起支付请求。
  4. 支付完成后,展示支付结果并处理回调。

总结

通过本项目,我们可以清晰地看到如何在 UniApp 中实现微信支付和支付宝支付。UniApp 提供了跨平台的支持,可以通过不同的平台条件来切换支付方式,并根据支付的结果给用户反馈。开发者可以在此基础上扩展更多支付功能,比如支付日志、订单查询等。

全部代码

订单支付页面代码

<template>
	<view>
		<view class="card option-pay">
			<view class="title">支付方式</view>
			<radio-group @change="payChange">
				<!-- #ifndef MP-WEIXIN -->
				<label class="pay-item center space-between">
					<view class="left center">
						<image src="/static/pay/alipay.png"></image>
						<text>支付宝</text>
					</view>
					<radio value="alipay" :checked="provider==='alipay'" style="transform:scale(0.8)" />
				</label>
				<!-- #endif -->
				<!-- #ifndef MP-ALIPAY -->
				<label class="pay-item center space-between">
					<view class="left center">
						<image src="/static/pay/wxpay.png"></image>
						<text>微信支付</text>
					</view>
					<radio value="wxpay" :checked="provider==='wxpay'" style="transform:scale(0.8)" />
				</label>
				<!-- #endif -->
			</radio-group>
		</view>
		<view class="card price space-between">
			<text>实付金额</text>
			<text>{{data.price}}</text>
		</view>
		<!-- #ifdef MP-WEIXIN -->
		<button class="btn" :loading="loading" :disabled="loading" @click="wxPayHandler">立即支付</button>
		<!-- #endif -->
		<!-- #ifndef MP-WEIXIN -->
		<button class="btn" :loading="loading" :disabled="loading" @click="payHandler">立即支付</button>
		<!-- #endif -->

	</view>
</template>
<script>
	import payMixin from './mixins/pay.js'
	export default {
		mixins: [payMixin],
		data() {
			return {
				// provider: 'alipay', // 支付方式,即提供商
				// data: {}
			}
		},
		onLoad(option) {
			//获取支付数据
			if (option.params) {
				this.data = JSON.parse(option.params)
			}
		},
		methods: {
			// payChange() {}
		}
	}
</script>
<style lang="scss">
	.card {
		margin: 0 30rpx;
		padding: 0 20rpx;
		background-color: #FFF;
		margin-top: 30rpx;
		border-radius: 20rpx;
		box-shadow: 1px 0 5px 0 rgba(0, 0, 0, 0.08);
	}

	.option-pay {
		.title {
			font-size: 35rpx;
			line-height: 90rpx;
			border-bottom: $wyk-underline;
		}

		.pay-item {
			line-height: 90rpx;

			.left {
				image {
					width: 60rpx;
					height: 60rpx;
				}

				text {
					font-size: 33rpx;
					padding-left: 20rpx;
				}
			}
		}
	}

	.price {
		font-size: 30rpx;
		line-height: 90rpx;
		border-bottom: 1px solid #F8F9FB;

		text:last-child {
			color: $mxg-text-color-red;
		}
	}

	.btn {
		margin: 60rpx 30rpx;
		background-color: $mxg-color-primary;
		color: #fff;
		line-height: 80rpx;
		font-size: 30rpx;

		&::after {
			// 加载中时,隐藏边框
			border: none;
		}
	}
</style>

mixins混合pay.js代码

import api from '@/api/order.js'
export default {
	data() {
		return {
			provider: 'alipay', // 支付方式,即提供商
			loading: false, // 是否提交中
			data: {}, //订单信息服务接口请求参数
		}
	},
	onLoad(option) {
		// #ifdef MP-WEIXIN
		// 微信小程序选中微信支付
		this.provider = 'wxpay'
		// #endif
	},
	methods: {
		// 选择支付方式
		payChange(e) {
			this.provider = e.detail.value
		},
		// 微信支付、支付宝操作
		async payHandler() {
			// 支付中
			this.loading = true
			// #ifdef APP-PLUS
			// 1. 发送请求到服务端,服务端生成订单信息,响应预支付订单号
			let orderInfo = await this.getOrderInfo();
			if (!orderInfo) {
				uni.showModal({
					content: '获取支付信息失败',
					showCancel: false
				})
				return
			}
			// 2. 请求支付
			uni.requestPayment({
				provider: this.provider, // 支付渠道
				orderInfo: orderInfo,
				success: (e) => {
					console.log("success", e);
					uni.showToast({
						title: "支付成功!"
					})
					// 回到订单页面
					this.navTo('/pages/order/order')
				},
				fail: (e) => {
					console.log("fail", e);
					uni.showModal({
						content: "支付失败,请重试。",
						showCancel: false
					})
				},
				complete: () => {
					this.loading = false;
				}
			})
			// #endif
		},
		// 获取订单信息 (微信小程序支付需要openid)
		getOrderInfo(openid) {
			// 不要少了async
			return new Promise(async (resolve, reject) => {
				if (openid) {
					// 微信小程序支付, 发送请求到服务器获取订单信息,参考:https: //pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_2.shtml
						let orderInfo = {
							"timeStamp": "1414561699",
							"nonceStr": "5K8264ILTKCH16CQ2502SI8ZNMTM67VS",
							"package": "prepay_id=wx201410272009395522657a690389285100", //预支付交易会话标识( prepay_id) "signType": "RSA",
							"paySign": "oR9d8PuhnIc+YZ8cBHFCwfgpaK9gd7vaRvkYD7rthRAZ\/X+QBhcCYL21N7cHCTUxbQ+EAt6Uy+lwSN22f5YZvI45MLko8Pfso0jm46v5hqcVwrk6uddkGuT + Cdvu4WBqDzaDjnNa5UK3GfE1Wfl2gHxIIY5lLdUgWFts17D4WuolLLkiFZV + JSHMvH7eaLdT9N5GBovBwu5yYKUR7skR8Fu + LozcSqQixnlEZUfyE55feLOQTUYzLmR9pNtPbPsu6WVhbNHMS3Ss2 + AehHvz + n64GDmXxbX++IOBvm2olHu3PsOUGRwhudhVf7UcGcunXt8cqNjKNqZLhLw4jq\ / xDg == ",
						}
					resolve(orderInfo)
					return
				}
				let res = null
				console.log('订单信息请求参数:', this.data)
				if (this.provider === 'alipay') {
					res = await api.getOrderInfoAlipay(this.data)
				} else if (this.provider === 'wxpay') {
					res = await api.getOrderInfoWxpay(this.data)
				}
				if (res && res.code === 20000) {
					resolve(res.data)
				} else {
					reject(new Error('获取支付信息失败' + res.message))
				}
			})
		},
		// 微信小程序支付
		async wxPayHandler() {
			this.loading = true
			// 1. 先获取用户code, 再获取openid
			let openid = uni.getStorageSync('openid')
			if (!openid) {
				try {
					openid = await this.loginWeixinMp()
				} catch (e) {
					console.error(e)
				}
				if (!openid) {
					uni.showModal({
						content: '获取openid失败',
						showCancel: false
					})
					this.loading = false
					return
				}
			}
			// 2. 通过 openid 再获取订单信息,
			let orderInfo = await this.getOrderInfo(openid)
			// 3. 通过订单预支付信息,去调用支付接口
			uni.requestPayment({
				...orderInfo,
				success: (res) => {
					uni.showToast({
						title: "支付成功!"
					})
				},
				fail: (res) => {
					uni.showModal({
						content: "支付失败,原因为: " + res.errMsg,
						showCancel: false
					})
				},
				complete: () => {
					this.loading = false;
				}
			})
		},
		// 登录微信小程序
		loginWeixinMp() {
			// 微信小程序登录参考:
			https: //developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
				return new Promise((resolve, reject) => {
					// 1. 先使用微信登录小程序响应 code,
					uni.login({
						provider: 'weixin',
						success: (res) => {
							console.log('登录', res)
							const code = res.code
							// 2. 请求服务端通过code获取openid
							let openid = 'xx'
							uni.setStorageSync('openid', openid)
							resolve(openid)
						},
						fail(err) {
							reject(err)
						}
					})
				})
		},
	}
}

实现效果

在 UniApp 中使用Mixins混合方法实现微信支付与支付宝支付
在 UniApp 中使用Mixins混合方法实现微信支付与支付宝支付
由于商品信息都是mock数据,code之类的也都是mock数据,所以导致失败,但是都可以调起微信支付和支付宝支付,打开微信和支付宝即为付款界面。
在 UniApp 中使用Mixins混合方法实现微信支付与支付宝支付

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值