Skip to main content

完成未支付订单

在订单列表中,我们需要实现一个功能,即用户可以点击“去支付”按钮来支付未完成的订单,而不是创建一个新的订单。在修改相关代码之前,我们需要先进行一些准备工作。

创建支付页面

首先,在0rder.vue文件中,我们给“去支付”按钮添加了一个v-on:click事件,并指定了pay(order)

frontend/src/views/Orders.vue
<tbody class="bg-white dark:bg-slate-800">

<tr v-for="order in info.results">
<td class="border-b border-slate-100 dark:border-slate-700 p-4 text-slate-500 dark:text-slate-400">{{ order.order_sn }}</td>
<td class="border-b border-slate-100 dark:border-slate-700 p-4 text-slate-500 dark:text-slate-400">{{ order.card.card_name }}</td>
<td class="border-b border-slate-100 dark:border-slate-700 p-4 text-slate-500 dark:text-slate-400"> {{ order.created_at }}</td>
<td class="border-b border-slate-100 dark:border-slate-700 p-4 text-slate-500 dark:text-slate-400">{{ order.order_mount }}</td>
<td class="border-b border-slate-100 dark:border-slate-700 py-4 text-slate-500 dark:text-slate-400">
<button v-if="order.pay_status == 'PAYING'" v-on:click="pay(order)" class="pay rounded border bg-gray-500 hover:bg-blue-500 hover:text-white text-sm h-8 w-16 text-primary-100">去支付</button>
<button v-else-if="order.pay_status == 'TRADE_CLOSED'" class="rounded border bg-gray-500 text-white text-sm h-8 w-16 cursor-not-allowed">已关闭</button>
<button v-else-if="order.pay_status == 'TRADE_SUCCESS' || order.pay_status == 'TRADE_FINISHED'" class="rounded border bg-blue-500 text-white text-sm h-8 w-16 cursor-default">已完成</button>
</td>
</tr>
</tbody>

然后,我们编写业务逻辑,执行pay()方法,代码如下:

frontend/src/views/Orders.vue
// 支付
pay(order) {
axios
.get('/api/alipay/?card_id='+ order.card.id + '&order_sn='+ order.order_sn)
.then(response => {
console.log(response.data)
window.location.href = response.data
})
}

上述代码中,当点击“去支付”时,会调用pay()方法,调用接口'/api/alipay/, 这个接口就是调用支付宝的接口,只是此时,我们携带了card_id和order_sn 2个参数。因为这个订单之前已经存在。

修改支付逻辑

alipay接口中,我们首先需要判断是否存在order_sn字段。如果不存在,则说明用户是从会员卡页面直接购买的,而不是在订单列表中重新支付。在这种情况下,我们将执行创建订单的逻辑。如果存在order_sn字段,则说明订单已经存在,我们需要根据订单号进行查找。如果能够找到订单且订单状态是正确的(比如等待支付状态),则将订单号赋值给out_trade_no,并发送支付请求。

trade/views.py文件中,AlipayAPIView类下修改get方法,代码如下:

dx_movie/trade/views.py
class AlipayAPIView(APIView):
def get(self, request):
card_id = request.GET.get('card_id', None)
try:
card = Card.objects.get(pk=card_id)
except:
return Response(response_data(*TradeError.CardParamsError))
order_sn = request.GET.get('order_sn', None)
if not order_sn:
out_trade_no = "pay" + datetime.now().strftime("%Y%m%d%H%M%S") + get_random_code(4)
# 创建订单
try:
Order.objects.create(
profile = Profile.objects.get(user=request.user),
card = card,
order_sn = out_trade_no,
order_mount = card.card_price,
pay_time = timezone.now() # 2023-09-13 15:32:58.148725+09:00
)
except:
return Response(response_data(*TradeError.OrderCreateError))
else:
try:
order = Order.objects.get(order_sn=order_sn)
if order.pay_status != 'PAYING':
return Response(response_data(*TradeError.OrderStatusError))
out_trade_no = order_sn
except:
return Response(response_data(*TradeError.OrderStatusError))

# 请求支付
try:
alipay = Alipay()
pay_url = alipay.trade_page( out_trade_no, str(card.card_price), card.card_name, '支付宝支付', 'FAST_INSTANT_TRADE_PAY')
return Response(pay_url)
except:
return Response(response_data(*TradeError.PayRequestError))

上述代码中,使用 if 判断 order_sn是否存在,如果不存在,就去执行新建,也就是我们之前使用的情况。而如果存在,去修改Order表的支付状态,代码如下:

dx_movie/trade/views.py
try:
order = Order.objects.get(order_sn=order_sn)
if order.pay_status != 'PAYING':
return Response(response_data(*TradeError.OrderStatusError))
out_trade_no = order_sn
except:
return Response(response_data(*TradeError.OrderStatusError))

在测试时,我们首先选择一个未支付的订单,点击“去支付”按钮。 图81-选择一个未支付订单

图81-填写用户名和密码去支付

支付成功后,订单状态将变为已完成。 图81-修改订单状态

下一节课中,我们将实现订单超时未支付自动关闭的功能。对于每个订单,超时时间不同。这样,我们就完成了未支付订单的支付功能。

以上就是本节的内容,谢谢大家!