123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- from re import U
- import uuid
- import os
- from typing import Optional
- from fastapi import FastAPI, Form, Depends, HTTPException, status
- from fastapi.templating import Jinja2Templates
- from dotenv import load_dotenv
- from os.path import join, dirname
- from linepay import LinePayApi
- from pydantic.networks import EmailStr
- from starlette.responses import HTMLResponse
- from sqlalchemy.orm import Session
- from fastapi.encoders import jsonable_encoder
- from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
- from sql.database import get_db_session
- from sql.crud import create_order, get_user
- from sql.models import order_info_linepay
- from sql.schemas import order_info_linepay as orderSechmas
- from sql.schemas import User
- from jose import JWTError, jwt
- from passlib.context import CryptContext
- # TBD load_env
- SECRET_KEY = "df2f77bd544240801a048bd4293afd8eeb7fff3cb7050e42c791db4b83ebadcd"
- ALGORITHM = "HS256"
- ACCESS_TOKEN_EXPIRE_DAYS = 5
- pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
- oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
- def verify_password(plain_password, hashed_password):
- return pwd_context.verify(plain_password, hashed_password)
- def get_password_hash(password):
- return pwd_context.hash(password)
- # dotenv
- dotenv_path = join(dirname(__file__),'./env/.env')
- # dotenv_path = join(dirname(__file__),'./env/test.env') ## sandbox
- load_dotenv(dotenv_path)
- # logger (TBD)
- # template
- templates = Jinja2Templates(directory="templates")
- # Line Pay Config
- LINE_PAY_CHANNEL_ID = os.environ.get("LINE_PAY_CHANNEL_ID")
- LINE_PAY_CHANNEL_SECRET = os.environ.get("LINE_PAY_CHANNEL_SECRET")
- LINE_PAY_REQEST_BASE_URL = "https://{}".format(os.environ.get("HOST_NAME"))
- line = LinePayApi(LINE_PAY_CHANNEL_ID, LINE_PAY_CHANNEL_SECRET, is_sandbox=False)
- # line = LinePayApi(LINE_PAY_CHANNEL_ID, LINE_PAY_CHANNEL_SECRET, is_sandbox=True)
- # CACHE
- CACHE = {}
- # Fastapi
- app = FastAPI()
- oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
- @app.get('/')
- def hello(token: str = Depends(oauth2_scheme)):
- index = {}
- index["product"] = "早鳥方案"
- index["amount"] = 1200
- index["url"] = "/request"
- # return {"product" : ,"amount" : 1200}
- return templates.TemplateResponse("index.html", {"request":index})
- ## Request
- @app.post('/request', response_class=HTMLResponse)
- async def pay_request(email: EmailStr= Form(...), phone: str= Form(...),full_name: str= Form(...)):
- order_id = str(uuid.uuid4())
- amount = 1200
- currency = "TWD"
- CACHE["email"] = email
- CACHE["phone"] = phone
- CACHE["full_name"] = full_name
- CACHE["orderid"] = order_id
- CACHE["amount"] = amount
- CACHE["currency"] = currency
- request_options ={
- "amount" : amount,
- "currency" : currency,
- "orderId" : order_id,
- "packages" : [
- {
- "id" : "早鳥方案",
- "amount" : 1200,
- "products" :[
- {
- # "id" : "Id_早鳥方案",
- "name" : "早鳥方案",
- "quantity" : 1,
- "price" : 1200,
- "imageUrl" : "https://kb.rspca.org.au/wp-content/uploads/2018/11/golder-retriever-puppy.jpeg"
- }
- ]
- }
- ],
- "redirectUrls" : {
- "confirmUrl" : LINE_PAY_REQEST_BASE_URL + "/confirm/",
- "cancelUrl" : LINE_PAY_REQEST_BASE_URL + "/cancel/"
- }
- }
- response = line.request(request_options)
- transaction_id = int(response.get("info",{}).get("transactionId",0))
- check_result = line.check_payment_status(transaction_id)
- response["transaction_id"] = transaction_id
- response["paymentStatusCheckReturnCode"] = check_result.get("returnCode", None)
- response["paymentStatusCheckReturnMessage"] = check_result.get("returnMessage", None)
- response["email"] = email
- response["phone"] = phone
- response["full_name"] = full_name
- return templates.TemplateResponse("request.html", {"request":response})
- # return response
- ## Confirm
- @app.get('/confirm/')
- async def pay_confirm(transactionId: int, orderId: Optional[str] = None, db_sesion: Session = Depends(get_db_session)):
- CACHE["transaction_id"] = transactionId
- response = line.confirm(transactionId,float(CACHE.get("amount",0)),CACHE.get("currency","TWD"))
- check_result = line.check_payment_status(transactionId)
- payment_details = line.payment_details(transaction_id=transactionId)
- response["transaction_id"] = transactionId
- response["paymentStatusCheckReturnCode"] = check_result.get("returnCode", None)
- response["paymentStatusCheckReturnMessage"] = check_result.get("returnMessage",None)
- response["payment_details"] = payment_details
- if(response["paymentStatusCheckReturnCode"] == '0123'):
- orderin = {}
- orderin["orderid"] = CACHE["orderid"]
- orderin["email"] = CACHE["email"]
- orderin["phone"] = CACHE["phone"]
- orderin["full_name"] = CACHE["full_name"]
- create_order(db_sesion, order_in= orderin)
- return templates.TemplateResponse("confirm.html", {"request":response})
- # return {"transactionId" : str(transactionId), "orderId" : orderId}
- ## Capture
- ## Refund
- ## Payment Details API
- @app.get('/payments')
- async def pay_payments(orderId : str):
- payment_details = line.payment_details(order_id=orderId)
- return payment_details
- ## Pay Preapproved API
|