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測試:
再來是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則會正常:
接著我們還要做一件事情:將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)
接著到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))
測試:
如此,我們就先完成了後端的結帳部分。
================================◉‿◉=================================
Day21結束了!在今天我們完成了paypal跟後端交互的部分,而明天我們將完成前端的結帳結合Paypal的部分,See ya next day!