Day21:21 - 结帐服务(5) - 後端 - 结帐 X PayPal Python Checkout SDK

Salom,我是Charlie!

在Day20的时候我们完成了createOrder跟CaptureOrder的Client,今天我们将把後端的结帐跟两个Client结合在一起。

================================◉‿◉=================================

首先是创立订单的部分,先在userorder当中建立在创立订单时,使用createOrderClient建立paypal金流的部分:

try:
	paypalresponse = CreateOrder().create_order(CURRENCY_CODE,totalvalue)
except Exception as e:
	return R.internalServerError(str(e))
else:
	data = fromPaypalResponse(paypalresponse)
	return R.ok(data)

因为paypalResponse不是json data所接受的格式,所以在下面建立fromPaypalResponse的方法:

def fromPaypalResponse(response):
	data = {}
	data["code"] = response.status_code
	data["status"] = response.result.status
	data["orderid"] = response.result.id
	data["intent"] = response.result.intent
	data["links"] = {}
	for link in response.result.links:
		data["links"][link.rel] = link.href
	data["total_Amount"] = response.result.purchase_units[0].amount.value
	return data

接着使用POSTMAN测试:
https://ithelp.ithome.com.tw/upload/images/20211005/20141666JMW8BLIPCU.png

再来是captureOrder的部分,先建立url的部分:

url(r'/capture/(?P<orderID>[\w+]{1,55})$',views.captureOrder),

接着在views当中建立captureOrder方法,使用CaptureOrderClient来收款:

@logincheck('POST')
def captureOrder(request,orderID = None):
	if not orderID:
		return R.badRequest("order id does not exist")
	if request.method == "POST":
		try:
			response = CaptureOrder().capture_order(orderID)
		except Exception as e:
			return R.internalServerError(str(e))
		else:
			return R.ok(fromCaptureResponse(response))
	else:
		return R.methodNotAllowed("method not allowed")

接着建立fromCaptureResponse方法,把capture传回的结果化为json:

def fromCaptureResponse(response):
	data = {}
	data["code"] = response.status_code
	data["status"] = response.result.status
	data["orderid"] = response.result.id
	data["links"] = {}
	for link in response.result.links:
		data["links"][link.rel] = link.href
	data["capture"] = []
	for purchase_unit in response.result.purchase_units:
		for capture in purchase_unit.payments.captures:
			data["capture"].append(capture.id)
	return data

测试,如果已经capture过的话会出现错误,如果第一次capture则会正常:
https://ithelp.ithome.com.tw/upload/images/20211005/20141666SVRgg42j7c.png

接着我们还要做一件事情:将paypal order id加入我们的资料库。

如果用户尚未付款的话,在订单详情页面一样能按下付款,同时,如果capture过了,必须要记录订单状态为paid。

所以我们先在models里面建立新栏位:

class Order(models.Model):
	id = models.AutoField(primary_key = True)
	orderno = models.CharField(max_length = 255,verbose_name = "订单编号")
	product = models.ForeignKey(Product,on_delete = models.CASCADE)
	user = models.ForeignKey(User,on_delete = models.CASCADE)
	amount = models.IntegerField(verbose_name = "商品数量")
	status = models.IntegerField(verbose_name = "状态")
	paypal_id = models.CharField(max_length = 255,verbose_name = "paypal订单编号")
	created_time = models.DateTimeField(auto_now = True)
	modified_time = models.DateTimeField(auto_now = True)

	class Meta:
		db_table = "orders"

并且执行迁移:

$ python manage.py makemigrations userorder
$ python manage.py migrate userorder

接着我们修改createOrder的程序码,创建paypal订单後把cart状态设为deactivate,并且储存order item:

totalvalue = 0
for cart in usercart:
	totalvalue += cart.amount * cart.product.price
try:
	paypalresponse = CreateOrder().create_order(CURRENCY_CODE,totalvalue)
except Exception as e:
	return R.internalServerError(str(e))
else:
	data = fromPaypalResponse(paypalresponse)
	paypal_id = data["orderid"]
	for cart in usercart:
		cart.status = CartStatus.deactivate.value
		cart.save()
		userorder = Order.objects.create(
			orderno = orderno,
			product = cart.product,
			user = cart.user,
			amount = cart.amount,
			status = OrderStatus.notPaid.value,
			paypal_id = paypal_id
		)		
	return R.ok(data)

https://ithelp.ithome.com.tw/upload/images/20211005/20141666kWTH1Q2y8Y.png
https://ithelp.ithome.com.tw/upload/images/20211005/20141666u7hiLYgLS8.png

接着到captureOrder,加上改变订单状态的程序码:

if request.method == "POST":
	try:
		response = CaptureOrder().capture_order(orderID)
	except Exception as e:
		return R.internalServerError(str(e))
	else:
		orders = Order.objects.filter(paypal_id = orderID)
		for order in orders:
			order.status = OrderStatus.paid.value
			order.save()
		return R.ok(fromCaptureResponse(response))

测试:
https://ithelp.ithome.com.tw/upload/images/20211005/20141666hRv8TDRPc0.png
https://ithelp.ithome.com.tw/upload/images/20211005/20141666KqczKtcMNI.png

如此,我们就先完成了後端的结帐部分。

================================◉‿◉=================================

Day21结束了!在今天我们完成了paypal跟後端交互的部分,而明天我们将完成前端的结帐结合Paypal的部分,See ya next day!


<<:  [Day 20]从零开始学习 JS 的连续-30 Days---todolist 待办事项

>>:  【踩坑】按钮闪阿闪,gradient 在 hover 时闪烁

Day 4:透过 npm、Hexo 指令在本机端安装你的 Hexo 部落格

当前置必要安装工具用好後,就可以在本机搭建 Hexo 部落格啦!安装过程会使用到指令,所以我们要打开...

Day18 使用 GCP 免费云端主机测试 Turn server

我们可以使用 GCP的免费方案 https://cloud.google.com/free/docs...

Material UI in React [ Day 18 ] Drawer (侧边栏)

Drawer 这个组件其实就是我们常用的 sidebar,继前一天的章节结合,就可以完成一个完整的应...

[Day16] THM Tomghost

网址 : https://tryhackme.com/room/tomghost IP : 10....

Day 26 : LightGBM 与 GridSearch

LightGBM GBDT(Gradient Boosting Decision Tree) 是利用...