|
@@ -3,65 +3,302 @@ from datetime import datetime
|
|
|
|
|
|
from fastapi import APIRouter, Body, Depends, HTTPException, Form, status, Response
|
|
|
from fastapi.encoders import jsonable_encoder
|
|
|
-from pydantic.networks import EmailStr
|
|
|
+from pydantic.networks import EmailStr, HttpUrl
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
|
|
-from app import crud, models, schemas
|
|
|
+import app.crud as crud
|
|
|
+import app.models as models
|
|
|
+import app.schemas as schemas
|
|
|
from app.api import deps
|
|
|
from app.core.config import settings
|
|
|
from app.core.ecpay_payment_sdk import ECPayPaymentSdk
|
|
|
from app.utils import send_new_account_email
|
|
|
-
|
|
|
+from pydantic import BaseModel
|
|
|
import requests
|
|
|
+from random import choice
|
|
|
+import string
|
|
|
+import json
|
|
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
-@router.post("/ecpay-result-return")
|
|
|
-def ecpay_return(
|
|
|
- *,
|
|
|
- MerchantID: Optional[str]=Form(None),
|
|
|
- MerchantTradeNo: Optional[str]=Form(None),
|
|
|
- StoreID: Optional[str]=Form(None),
|
|
|
- RtnCode: Optional[int]=Form(None),
|
|
|
- RtnMsg: Optional[str]=Form(None),
|
|
|
- TradeNo: Optional[str]=Form(None),
|
|
|
- TradeAmt: Optional[int]=Form(None),
|
|
|
- PaymentDate: Optional[str]=Form(None),
|
|
|
- PaymentType: Optional[str]=Form(None),
|
|
|
- PaymentTypeChargeFee: Optional[int]=Form(None),
|
|
|
- TradeDate: Optional[str]=Form(None),
|
|
|
- SimulatePaid: Optional[int]=Form(None),
|
|
|
- CustomField1: Optional[str]=Form(None),
|
|
|
- CustomField2: Optional[str]=Form(None),
|
|
|
- CustomField3: Optional[str]=Form(None),
|
|
|
- CustomField4: Optional[str]=Form(None),
|
|
|
- CheckMacValue: Optional[str]=Form(None),
|
|
|
-) -> Any:
|
|
|
- #送email
|
|
|
- print(f"\
|
|
|
-MerchantID: {MerchantID} \n\
|
|
|
-MerchantTradeNo: {MerchantTradeNo}\n\
|
|
|
-StoreID: {StoreID}\n\
|
|
|
-RtnCode: {RtnCode}\n\
|
|
|
-RtnMsg: {RtnMsg}\n\
|
|
|
-TradeNo: {TradeNo}\n\
|
|
|
-TradeAmt: {TradeAmt}\n\
|
|
|
-PaymentDate: {PaymentDate}\n\
|
|
|
-PaymentType: {PaymentType}\n\
|
|
|
-PaymentTypeChargeFee: {PaymentTypeChargeFee}\n\
|
|
|
-TradeDate: {TradeDate}\n\
|
|
|
-SimulatePaid: {SimulatePaid}\n\
|
|
|
-CustomField1: {CustomField1}\n\
|
|
|
-CustomField2: {CustomField2}\n\
|
|
|
-CustomField3: {CustomField3}\n\
|
|
|
-CustomField4: {CustomField4}\n\
|
|
|
-CheckMacValue: {CheckMacValue}\
|
|
|
- ")
|
|
|
- return Response(content='1', status_code=status.HTTP_200_OK)
|
|
|
+@router.post('/ecpay-test-payment')
|
|
|
+def ecpay_payment(
|
|
|
+ *,
|
|
|
+ db: Session = Depends(deps.get_db),
|
|
|
+ current_user: models.User = Depends(deps.get_current_active_user),
|
|
|
+ payment_data: schemas.PaymentCreate,
|
|
|
+ lang: str=''
|
|
|
+):
|
|
|
+ print(payment_data)
|
|
|
+ MerchantTradeNo = 'test'+datetime.now().strftime("NO%Y%m%d%H%M%S")
|
|
|
+ remark = {'MerchantTradeNo':MerchantTradeNo}
|
|
|
+ remark_string = json.dumps(remark, ensure_ascii=False)
|
|
|
+ payment = crud.payment.create_with_payment_data(db,
|
|
|
+ obj_in=payment_data,
|
|
|
+ owner_id=current_user.id,
|
|
|
+ epayment='ecpay',
|
|
|
+ remark=remark_string)
|
|
|
+ items = payment_data.item
|
|
|
+ items = items.split("#")
|
|
|
+ print(payment.item)
|
|
|
+ content = {}
|
|
|
+ for item in items:
|
|
|
+ pair = item.split()
|
|
|
+ content[str(pair[0]).lower()] = pair[1]
|
|
|
+ content_string = json.dumps(content, ensure_ascii=False).replace('"', "'")
|
|
|
+ order_params = {
|
|
|
+ 'MerchantTradeNo': MerchantTradeNo,
|
|
|
+ 'StoreID': 'SaaS',
|
|
|
+ 'MerchantTradeDate': datetime.now().strftime("%Y/%m/%d %H:%M:%S"),
|
|
|
+ 'PaymentType': 'aio',
|
|
|
+ 'TotalAmount': payment_data.amount,
|
|
|
+ 'TradeDesc': 'SaaS訂單',
|
|
|
+ 'ItemName': payment_data.item,
|
|
|
+ 'ReturnURL': 'https://cloud.choozmo.com/api/v1/payment/ecpay-result-return',
|
|
|
+ 'ChoosePayment': 'ALL',
|
|
|
+ 'ClientBackURL': 'https://cloud.choozmo.com/payment',
|
|
|
+ 'ItemURL': 'https://cloud.choozmo.com/payment',
|
|
|
+ 'Remark': '',
|
|
|
+ 'ChooseSubPayment': '',
|
|
|
+ 'OrderResultURL': '',
|
|
|
+ 'NeedExtraPaidInfo': 'Y',
|
|
|
+ 'DeviceSource': '',
|
|
|
+ 'IgnorePayment': 'ATM#CVS#BARCODE',
|
|
|
+ 'PlatformID': '',
|
|
|
+ 'InvoiceMark': 'N',
|
|
|
+ 'CustomField1': f'{str(payment.id)}',
|
|
|
+ 'CustomField2': f'{str(current_user.id)}',
|
|
|
+ 'CustomField3': content_string,
|
|
|
+ 'CustomField4': '',
|
|
|
+ 'EncryptType': 1,
|
|
|
+ 'Language': lang,
|
|
|
+ }
|
|
|
+ print(order_params)
|
|
|
+ extend_params_1 = {
|
|
|
+ 'ExpireDate': 7,
|
|
|
+ 'PaymentInfoURL': 'https://www.ecpay.com.tw/payment_info_url.php',
|
|
|
+ 'ClientRedirectURL': '',
|
|
|
+ }
|
|
|
+
|
|
|
+ extend_params_2 = {
|
|
|
+ 'StoreExpireDate': 15,
|
|
|
+ 'Desc_1': '',
|
|
|
+ 'Desc_2': '',
|
|
|
+ 'Desc_3': '',
|
|
|
+ 'Desc_4': '',
|
|
|
+ 'PaymentInfoURL': 'https://www.ecpay.com.tw/payment_info_url.php',
|
|
|
+ 'ClientRedirectURL': '',
|
|
|
+ }
|
|
|
+
|
|
|
+ extend_params_3 = {
|
|
|
+ 'BindingCard': 0,
|
|
|
+ 'MerchantMemberID': '',
|
|
|
+ }
|
|
|
+
|
|
|
+ extend_params_4 = {
|
|
|
+ 'Redeem': 'N',
|
|
|
+ 'UnionPay': 0,
|
|
|
+ }
|
|
|
+
|
|
|
+ inv_params = {
|
|
|
+ # 'RelateNumber': 'Tea0001', # 特店自訂編號
|
|
|
+ # 'CustomerID': 'TEA_0000001', # 客戶編號
|
|
|
+ # 'CustomerIdentifier': '53348111', # 統一編號
|
|
|
+ # 'CustomerName': '客戶名稱',
|
|
|
+ # 'CustomerAddr': '客戶地址',
|
|
|
+ # 'CustomerPhone': '0912345678', # 客戶手機號碼
|
|
|
+ # 'CustomerEmail': 'abc@ecpay.com.tw',
|
|
|
+ # 'ClearanceMark': '2', # 通關方式
|
|
|
+ # 'TaxType': '1', # 課稅類別
|
|
|
+ # 'CarruerType': '', # 載具類別
|
|
|
+ # 'CarruerNum': '', # 載具編號
|
|
|
+ # 'Donation': '1', # 捐贈註記
|
|
|
+ # 'LoveCode': '168001', # 捐贈碼
|
|
|
+ # 'Print': '1',
|
|
|
+ # 'InvoiceItemName': '測試商品1|測試商品2',
|
|
|
+ # 'InvoiceItemCount': '2|3',
|
|
|
+ # 'InvoiceItemWord': '個|包',
|
|
|
+ # 'InvoiceItemPrice': '35|10',
|
|
|
+ # 'InvoiceItemTaxType': '1|1',
|
|
|
+ # 'InvoiceRemark': '測試商品1的說明|測試商品2的說明',
|
|
|
+ # 'DelayDay': '0', # 延遲天數
|
|
|
+ # 'InvType': '07', # 字軌類別
|
|
|
+ }
|
|
|
+
|
|
|
+ # 建立實體
|
|
|
+ ecpay_payment_sdk = ECPayPaymentSdk(
|
|
|
+ MerchantID='3002607',
|
|
|
+ HashKey='pwFHCqoQZGmho4w6',
|
|
|
+ HashIV='EkRm7iFT261dpevs'
|
|
|
+ )
|
|
|
+
|
|
|
+ # 合併延伸參數
|
|
|
+ order_params.update(extend_params_1)
|
|
|
+ order_params.update(extend_params_2)
|
|
|
+ order_params.update(extend_params_3)
|
|
|
+ order_params.update(extend_params_4)
|
|
|
+
|
|
|
+ # 合併發票參數
|
|
|
+ order_params.update(inv_params)
|
|
|
+ try:
|
|
|
+ # 產生綠界訂單所需參數
|
|
|
+ final_order_params = ecpay_payment_sdk.create_order(order_params)
|
|
|
+
|
|
|
+ # 產生 html 的 form 格式
|
|
|
+ action_url = 'https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5' # 測試環境
|
|
|
+ # action_url = 'https://payment.ecpay.com.tw/Cashier/AioCheckOut/V5' # 正式環境
|
|
|
+ html = ecpay_payment_sdk.gen_html_post_form(action_url, final_order_params)
|
|
|
+
|
|
|
+ return html
|
|
|
+ except Exception as error:
|
|
|
+ print('An exception happened: ' + str(error))
|
|
|
+
|
|
|
+@router.post('/ecpay-payment')
|
|
|
+def ecpay_payment(
|
|
|
+ *,
|
|
|
+ db: Session = Depends(deps.get_db),
|
|
|
+ current_user: models.User = Depends(deps.get_current_active_user),
|
|
|
+ payment_data: schemas.PaymentCreate,
|
|
|
+ lang: str=''
|
|
|
+):
|
|
|
+ print(payment_data)
|
|
|
+ numbers = string.digits
|
|
|
+ randomNumber = ''.join(choice(numbers) for _ in range(4))
|
|
|
+ MerchantTradeNo = datetime.now().strftime("%Y%m%d%H%M%SNO")+randomNumber
|
|
|
+ remark = {'MerchantTradeNo':MerchantTradeNo}
|
|
|
+ remark_string = json.dumps(remark, ensure_ascii=False)
|
|
|
+ payment = crud.payment.create_with_payment_data(db,
|
|
|
+ obj_in=payment_data,
|
|
|
+ owner_id=current_user.id,
|
|
|
+ epayment='ecpay',
|
|
|
+ remark=remark_string)
|
|
|
+ items = payment_data.item
|
|
|
+ items = items.split("#")
|
|
|
+ content = {}
|
|
|
+ for item in items:
|
|
|
+ pair = item.split()
|
|
|
+ content[str(pair[0]).lower()] = pair[1]
|
|
|
+ content_string = json.dumps(content, ensure_ascii=False)
|
|
|
+ order_params = {
|
|
|
+ 'MerchantTradeNo': MerchantTradeNo,
|
|
|
+ 'StoreID': 'SaaS',
|
|
|
+ 'MerchantTradeDate': datetime.now().strftime("%Y/%m/%d %H:%M:%S"),
|
|
|
+ 'PaymentType': 'aio',
|
|
|
+ 'TotalAmount': payment_data.amount,
|
|
|
+ 'TradeDesc': 'SaaS訂單',
|
|
|
+ 'ItemName': payment_data.item,
|
|
|
+ 'ReturnURL': 'https://cloud.choozmo.com/api/v1/payment/ecpay-result-return',
|
|
|
+ 'ChoosePayment': 'ALL',
|
|
|
+ 'ClientBackURL': 'https://cloud.choozmo.com/main/admin/test-payment',
|
|
|
+ 'ItemURL': 'https://cloud.choozmo.com/main/admin/test-payment',
|
|
|
+ 'Remark': '',
|
|
|
+ 'ChooseSubPayment': '',
|
|
|
+ 'OrderResultURL': '',
|
|
|
+ 'NeedExtraPaidInfo': 'Y',
|
|
|
+ 'DeviceSource': '',
|
|
|
+ 'IgnorePayment': 'ATM#CVS#BARCODE',
|
|
|
+ 'PlatformID': '',
|
|
|
+ 'InvoiceMark': 'N',
|
|
|
+ 'CustomField1': str(payment.id),
|
|
|
+ 'CustomField2': str(current_user.id),
|
|
|
+ 'CustomField3': content_string,
|
|
|
+ 'CustomField4': '',
|
|
|
+ 'EncryptType': 1,
|
|
|
+ 'Language': lang,
|
|
|
+ }
|
|
|
+
|
|
|
+ extend_params_1 = {
|
|
|
+ 'ExpireDate': 7,
|
|
|
+ 'PaymentInfoURL': 'https://www.ecpay.com.tw/payment_info_url.php',
|
|
|
+ 'ClientRedirectURL': '',
|
|
|
+ }
|
|
|
+
|
|
|
+ extend_params_2 = {
|
|
|
+ 'StoreExpireDate': 15,
|
|
|
+ 'Desc_1': '',
|
|
|
+ 'Desc_2': '',
|
|
|
+ 'Desc_3': '',
|
|
|
+ 'Desc_4': '',
|
|
|
+ 'PaymentInfoURL': 'https://www.ecpay.com.tw/payment_info_url.php',
|
|
|
+ 'ClientRedirectURL': '',
|
|
|
+ }
|
|
|
|
|
|
-@router.post("/ecpay-test-result-return")
|
|
|
+ extend_params_3 = {
|
|
|
+ 'BindingCard': 0,
|
|
|
+ 'MerchantMemberID': '',
|
|
|
+ }
|
|
|
+
|
|
|
+ extend_params_4 = {
|
|
|
+ 'Redeem': 'N',
|
|
|
+ 'UnionPay': 0,
|
|
|
+ }
|
|
|
+
|
|
|
+ inv_params = {
|
|
|
+ # 'RelateNumber': 'Tea0001', # 特店自訂編號
|
|
|
+ # 'CustomerID': 'TEA_0000001', # 客戶編號
|
|
|
+ # 'CustomerIdentifier': '53348111', # 統一編號
|
|
|
+ # 'CustomerName': '客戶名稱',
|
|
|
+ # 'CustomerAddr': '客戶地址',
|
|
|
+ # 'CustomerPhone': '0912345678', # 客戶手機號碼
|
|
|
+ # 'CustomerEmail': 'abc@ecpay.com.tw',
|
|
|
+ # 'ClearanceMark': '2', # 通關方式
|
|
|
+ # 'TaxType': '1', # 課稅類別
|
|
|
+ # 'CarruerType': '', # 載具類別
|
|
|
+ # 'CarruerNum': '', # 載具編號
|
|
|
+ # 'Donation': '1', # 捐贈註記
|
|
|
+ # 'LoveCode': '168001', # 捐贈碼
|
|
|
+ # 'Print': '1',
|
|
|
+ # 'InvoiceItemName': '測試商品1|測試商品2',
|
|
|
+ # 'InvoiceItemCount': '2|3',
|
|
|
+ # 'InvoiceItemWord': '個|包',
|
|
|
+ # 'InvoiceItemPrice': '35|10',
|
|
|
+ # 'InvoiceItemTaxType': '1|1',
|
|
|
+ # 'InvoiceRemark': '測試商品1的說明|測試商品2的說明',
|
|
|
+ # 'DelayDay': '0', # 延遲天數
|
|
|
+ # 'InvType': '07', # 字軌類別
|
|
|
+ }
|
|
|
+
|
|
|
+ # 建立實體
|
|
|
+ ecpay_payment_sdk = ECPayPaymentSdk(
|
|
|
+ MerchantID='3226141',
|
|
|
+ HashKey='OhcjDTeXK9PKW9vb',
|
|
|
+ HashIV='AfOmUM06S0bt8KPE'
|
|
|
+ )
|
|
|
+
|
|
|
+ # 合併延伸參數
|
|
|
+ order_params.update(extend_params_1)
|
|
|
+ order_params.update(extend_params_2)
|
|
|
+ order_params.update(extend_params_3)
|
|
|
+ order_params.update(extend_params_4)
|
|
|
+
|
|
|
+ # 合併發票參數
|
|
|
+ order_params.update(inv_params)
|
|
|
+ try:
|
|
|
+ # 產生綠界訂單所需參數
|
|
|
+ final_order_params = ecpay_payment_sdk.create_order(order_params)
|
|
|
+
|
|
|
+ # 產生 html 的 form 格式
|
|
|
+ # action_url = 'https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5' # 測試環境
|
|
|
+ action_url = 'https://payment.ecpay.com.tw/Cashier/AioCheckOut/V5' # 正式環境
|
|
|
+ html = ecpay_payment_sdk.gen_html_post_form(action_url, final_order_params)
|
|
|
+
|
|
|
+ return html
|
|
|
+ except Exception as error:
|
|
|
+ print('An exception happened: ' + str(error))
|
|
|
+
|
|
|
+
|
|
|
+@router.get('/list-all', response_model=List[schemas.YTViews])
|
|
|
+def get_list(
|
|
|
+ *,
|
|
|
+ db: Session = Depends(deps.get_db),
|
|
|
+):
|
|
|
+ ytviews_list = crud.ytviews.get_multi(db)
|
|
|
+ return ytviews_list
|
|
|
+
|
|
|
+@router.post("/ecpay-result-return")
|
|
|
def ecpay_return(
|
|
|
*,
|
|
|
+ db: Session = Depends(deps.get_db),
|
|
|
MerchantID: Optional[str]=Form(None),
|
|
|
MerchantTradeNo: Optional[str]=Form(None),
|
|
|
StoreID: Optional[str]=Form(None),
|
|
@@ -100,13 +337,17 @@ CustomField3: {CustomField3}\n\
|
|
|
CustomField4: {CustomField4}\n\
|
|
|
CheckMacValue: {CheckMacValue}\
|
|
|
")
|
|
|
- return Response(content='1', status_code=status.HTTP_200_OK)
|
|
|
-
|
|
|
-
|
|
|
-@router.get('/check-payment-list')
|
|
|
-def get_payment_list(
|
|
|
- *,
|
|
|
- db: Session = Depends(deps.get_db),
|
|
|
- current_user: models.User = Depends(deps.get_current_active_user)
|
|
|
-):
|
|
|
- pass
|
|
|
+
|
|
|
+ if RtnCode==1:
|
|
|
+ payment_id = int(CustomField1)
|
|
|
+ payment = crud.ytviews.get(db=db, id=payment_id)
|
|
|
+ remark = json.loads(payment.remark)
|
|
|
+ remark['TradeNo'] = TradeNo
|
|
|
+ content_string = CustomField3.replace("'",'"')
|
|
|
+ content:dict = json.loads(content_string)
|
|
|
+ if 'credit' in content.keys:
|
|
|
+ add_credit = content['credit']
|
|
|
+ if user := crud.user.get(id=int(CustomField2)):
|
|
|
+ user.update(db, db_obj=payment, obj_in={"available_time": user.available_tiem + int(add_credit)})
|
|
|
+ crud.payment.update(db, db_obj=payment, obj_in={"payment_state":"succeeded", "remark":json.dumps(remark, ensure_ascii=False)})
|
|
|
+ return Response(content='1', status_code=status.HTTP_200_OK)
|