main.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import dotenv
  2. import uuid
  3. import os
  4. import logging
  5. from typing import AsyncContextManager, Optional
  6. from fastapi import FastAPI, Request, responses
  7. from fastapi.params import Depends
  8. from fastapi.templating import Jinja2Templates
  9. from pydantic import BaseModel
  10. from dotenv import load_dotenv
  11. from os.path import join, dirname
  12. from linepay import LinePayApi
  13. from pydantic.errors import UrlSchemeError
  14. from starlette.responses import HTMLResponse
  15. from pydantic import BaseModel, EmailStr, validator
  16. from sqlalchemy.orm import Session
  17. from . import crud, models, schemas
  18. from .database import SessionLocal, engine
  19. # dotenv
  20. dotenv_path = join(dirname(__file__),'./env/.env')
  21. # dotenv_path = join(dirname(__file__),'./env/test.env') ## sandbox
  22. load_dotenv(dotenv_path)
  23. # logger (TBD)
  24. # template
  25. templates = Jinja2Templates(directory="templates")
  26. # Line Pay Config
  27. LINE_PAY_CHANNEL_ID = os.environ.get("LINE_PAY_CHANNEL_ID")
  28. LINE_PAY_CHANNEL_SECRET = os.environ.get("LINE_PAY_CHANNEL_SECRET")
  29. LINE_PAY_REQEST_BASE_URL = "https://{}".format(os.environ.get("HOST_NAME"))
  30. line = LinePayApi(LINE_PAY_CHANNEL_ID, LINE_PAY_CHANNEL_SECRET, is_sandbox=False)
  31. # line = LinePayApi(LINE_PAY_CHANNEL_ID, LINE_PAY_CHANNEL_SECRET, is_sandbox=True)
  32. # CACHE
  33. CACHE = {}
  34. # db
  35. models.Base.metadata.create_all(bind=engine)
  36. # Fastapi
  37. app = FastAPI()
  38. @app.get('/')
  39. def hellow():
  40. return {"Hello" : "World"}
  41. ## Request
  42. @app.post('/request', response_class=HTMLResponse)
  43. async def pay_request(userinfo: schemas.UserInfo, db: Session = Depends(get_db)):
  44. order_id = str(uuid.uuid4())
  45. amount = 1200
  46. currency = "TWD"
  47. CACHE["order_id"] = order_id
  48. CACHE["amount"] = amount
  49. CACHE["currency"] = currency
  50. request_options ={
  51. "amount" : amount,
  52. "currency" : currency,
  53. "orderId" : order_id,
  54. "packages" : [
  55. {
  56. "id" : "早鳥方案",
  57. "amount" : 1200,
  58. "products" :[
  59. {
  60. # "id" : "Id_早鳥方案",
  61. "name" : "早鳥方案",
  62. "quantity" : 1,
  63. "price" : 1200,
  64. "imageUrl" : "https://kb.rspca.org.au/wp-content/uploads/2018/11/golder-retriever-puppy.jpeg"
  65. }
  66. ]
  67. }
  68. ],
  69. "redirectUrls" : {
  70. "confirmUrl" : LINE_PAY_REQEST_BASE_URL + "/confirm/",
  71. "cancelUrl" : LINE_PAY_REQEST_BASE_URL + "/cancel/"
  72. }
  73. }
  74. response = line.request(request_options)
  75. transaction_id = int(response.get("info",{}).get("transactionId",0))
  76. check_result = line.check_payment_status(transaction_id)
  77. response["transaction_id"] = transaction_id
  78. response["paymentStatusCheckReturnCode"] = check_result.get("returnCode", None)
  79. response["paymentStatusCheckReturnMessage"] = check_result.get("returnMessage", None)
  80. return templates.TemplateResponse("request.html", {"request":response})
  81. # return response
  82. ## Confirm
  83. @app.get('/confirm/')
  84. async def pay_confirm(transactionId: int, orderId: Optional[str] = None):
  85. CACHE["transaction_id"] = transactionId
  86. response = line.confirm(transactionId,float(CACHE.get("amount",0)),CACHE.get("currency","TWD"))
  87. check_result = line.check_payment_status(transactionId)
  88. payment_details = line.payment_details(transaction_id=transactionId)
  89. response["transaction_id"] = transactionId
  90. response["paymentStatusCheckReturnCode"] = check_result.get("returnCode", None)
  91. response["paymentStatusCheckReturnMessage"] = check_result.get("returnMessage",None)
  92. response["payment_details"] = payment_details
  93. return templates.TemplateResponse("confirm.html", {"request":response})
  94. # return {"transactionId" : str(transactionId), "orderId" : orderId}
  95. ## Capture
  96. ## Refund
  97. ## Payment Details API
  98. @app.get('/payments')
  99. async def pay_payments(orderId : str):
  100. payment_details = line.payment_details(order_id=orderId)
  101. return payment_details
  102. ## Pay Preapproved API