|
@@ -0,0 +1,328 @@
|
|
|
+from typing import Any, List, Optional
|
|
|
+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, HttpUrl
|
|
|
+from sqlalchemy.orm import Session
|
|
|
+
|
|
|
+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('/simple-ecpay-test-payment')
|
|
|
+def ecpay_payment(
|
|
|
+ *,
|
|
|
+ db: Session = Depends(deps.get_db),
|
|
|
+ user_data: schemas.SimplePayCreate,
|
|
|
+ lang: str=''
|
|
|
+):
|
|
|
+ print(user_data.url)
|
|
|
+ MerchantTradeNo = 'test'+datetime.now().strftime("NO%Y%m%d%H%M%S")
|
|
|
+ remark = {'MerchantTradeNo':MerchantTradeNo}
|
|
|
+ remark_string = json.dumps(remark, ensure_ascii=False)
|
|
|
+ ytviews = crud.simplepay.create_with_payment_data(db,
|
|
|
+ obj_in=user_data,
|
|
|
+ epayment='ecpay',
|
|
|
+ remark=remark_string)
|
|
|
+ order_params = {
|
|
|
+ 'MerchantTradeNo': MerchantTradeNo,
|
|
|
+ 'StoreID': 'SaaS',
|
|
|
+ 'MerchantTradeDate': datetime.now().strftime("%Y/%m/%d %H:%M:%S"),
|
|
|
+ 'PaymentType': 'aio',
|
|
|
+ 'TotalAmount': user_data.amount,
|
|
|
+ 'TradeDesc': user_data.tradeDesc,
|
|
|
+ 'ItemName': user_data.item,
|
|
|
+ 'ReturnURL': 'https://cloud.choozmo.com/api/v1/payment/ytviews-ecpay-result-return',
|
|
|
+ 'ChoosePayment': 'ALL',
|
|
|
+ 'ClientBackURL': 'https://cloud.choozmo.com/test-yt-views',
|
|
|
+ 'ItemURL': 'https://cloud.choozmo.com/test-yt-views',
|
|
|
+ 'Remark': '',
|
|
|
+ 'ChooseSubPayment': '',
|
|
|
+ 'OrderResultURL': '',
|
|
|
+ 'NeedExtraPaidInfo': 'Y',
|
|
|
+ 'DeviceSource': '',
|
|
|
+ 'IgnorePayment': 'ATM#CVS#BARCODE',
|
|
|
+ 'PlatformID': '',
|
|
|
+ 'InvoiceMark': 'N',
|
|
|
+ 'CustomField1': str(ytviews.id),
|
|
|
+ 'CustomField2': user_data.taxID if user_data.taxID else '',
|
|
|
+ 'CustomField3': '',
|
|
|
+ 'CustomField4': '',
|
|
|
+ 'EncryptType': 1,
|
|
|
+ 'Language': lang,
|
|
|
+ }
|
|
|
+
|
|
|
+ extend_params_1 = {
|
|
|
+ 'ExpireDate': 3,
|
|
|
+ 'PaymentInfoURL': 'https://www.ecpay.com.tw/payment_info_url.php',
|
|
|
+ 'ClientRedirectURL': '',
|
|
|
+ }
|
|
|
+
|
|
|
+ extend_params_2 = {
|
|
|
+ 'StoreExpireDate': 7,
|
|
|
+ '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('/simpley-ecpay-payment')
|
|
|
+def ecpay_payment(
|
|
|
+ *,
|
|
|
+ db: Session = Depends(deps.get_db),
|
|
|
+ user_data: schemas.SimplePayCreate,
|
|
|
+ lang: str=''
|
|
|
+):
|
|
|
+ print(user_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)
|
|
|
+ simplay = crud.simplepay.create_with_payment_data(db,
|
|
|
+ obj_in=user_data,
|
|
|
+ epayment='ecpay',
|
|
|
+ remark=remark_string)
|
|
|
+ order_params = {
|
|
|
+ 'MerchantTradeNo': MerchantTradeNo,
|
|
|
+ 'StoreID': 'SaaS',
|
|
|
+ 'MerchantTradeDate': datetime.now().strftime("%Y/%m/%d %H:%M:%S"),
|
|
|
+ 'PaymentType': 'aio',
|
|
|
+ 'TotalAmount': user_data.amount,
|
|
|
+ 'TradeDesc': user_data.tradeDesc,
|
|
|
+ 'ItemName': user_data.item,
|
|
|
+ 'ReturnURL': 'https://cloud.choozmo.com/api/v1/payment/ytviews-ecpay-result-return',
|
|
|
+ 'ChoosePayment': 'ALL',
|
|
|
+ 'ClientBackURL': 'https://cloud.choozmo.com/yt-views',
|
|
|
+ 'ItemURL': 'https://cloud.choozmo.com/yt-views',
|
|
|
+ 'Remark': '',
|
|
|
+ 'ChooseSubPayment': '',
|
|
|
+ 'OrderResultURL': '',
|
|
|
+ 'NeedExtraPaidInfo': 'Y',
|
|
|
+ 'DeviceSource': '',
|
|
|
+ 'IgnorePayment': 'ATM#CVS#BARCODE',
|
|
|
+ 'PlatformID': '',
|
|
|
+ 'InvoiceMark': 'N',
|
|
|
+ 'CustomField1': str(simplepay.id),
|
|
|
+ 'CustomField2': user_data.taxID if user_data.taxID else '',
|
|
|
+ 'CustomField3': '',
|
|
|
+ 'CustomField4': '',
|
|
|
+ 'EncryptType': 1,
|
|
|
+ 'Language': lang,
|
|
|
+ }
|
|
|
+
|
|
|
+ extend_params_1 = {
|
|
|
+ 'ExpireDate': 3,
|
|
|
+ 'PaymentInfoURL': 'https://www.ecpay.com.tw/payment_info_url.php',
|
|
|
+ 'ClientRedirectURL': '',
|
|
|
+ }
|
|
|
+
|
|
|
+ extend_params_2 = {
|
|
|
+ 'StoreExpireDate': 7,
|
|
|
+ '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='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('/simpleypay-list-all', response_model=List[schemas.SimplePay])
|
|
|
+def get_list(
|
|
|
+ *,
|
|
|
+ db: Session = Depends(deps.get_db),
|
|
|
+):
|
|
|
+ simplepay_list = crud.simplepay.get_multi(db)
|
|
|
+ return
|
|
|
+
|
|
|
+@router.post("/simple-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),
|
|
|
+ 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}\
|
|
|
+ ")
|
|
|
+
|
|
|
+ if RtnCode==1:
|
|
|
+ simplepay_id = int(CustomField1)
|
|
|
+ simplepay = crud.simplepay.get(db=db, id=ytviews_id)
|
|
|
+ remark = json.loads(simplepay.remark)
|
|
|
+ remark['TradeNo'] = TradeNo
|
|
|
+ crud.simplepay.update(db, db_obj=simplepay, obj_in={"payment_state":"succeeded", "remark":json.dumps(remark, ensure_ascii=False)})
|
|
|
+ return Response(content='1', status_code=status.HTTP_200_OK)
|