ytviewspayment.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. from typing import Any, List, Optional
  2. from datetime import datetime
  3. from fastapi import APIRouter, Body, Depends, HTTPException, Form, status, Response
  4. from fastapi.encoders import jsonable_encoder
  5. from pydantic.networks import EmailStr, HttpUrl
  6. from sqlalchemy.orm import Session
  7. import app.crud as crud
  8. import app.models as models
  9. import app.schemas as schemas
  10. from app.api import deps
  11. from app.core.config import settings
  12. from app.core.ecpay_payment_sdk import ECPayPaymentSdk
  13. from app.utils import send_new_account_email
  14. from pydantic import BaseModel
  15. import requests
  16. from random import choice
  17. import string
  18. import json
  19. router = APIRouter()
  20. @router.post('/ytviews-ecpay-test-payment')
  21. def ecpay_payment(
  22. *,
  23. db: Session = Depends(deps.get_db),
  24. user_data: schemas.YTViewsCreate,
  25. lang: str=''
  26. ):
  27. print(user_data.url)
  28. MerchantTradeNo = 'test'+datetime.now().strftime("NO%Y%m%d%H%M%S")
  29. remark = {'MerchantTradeNo':MerchantTradeNo}
  30. remark_string = json.dumps(remark, ensure_ascii=False)
  31. ytviews = crud.ytviews.create_with_payment_data(db,
  32. obj_in=user_data,
  33. epayment='ecpay',
  34. remark=remark_string)
  35. order_params = {
  36. 'MerchantTradeNo': MerchantTradeNo,
  37. 'StoreID': 'SaaS',
  38. 'MerchantTradeDate': datetime.now().strftime("%Y/%m/%d %H:%M:%S"),
  39. 'PaymentType': 'aio',
  40. 'TotalAmount': user_data.amount,
  41. 'TradeDesc': 'YT0.4訂單測試',
  42. 'ItemName': user_data.item,
  43. 'ReturnURL': 'https://cloud.choozmo.com/api/v1/payment/ytviews-ecpay-result-return',
  44. 'ChoosePayment': 'ALL',
  45. 'ClientBackURL': 'https://cloud.choozmo.com/test-yt-views',
  46. 'ItemURL': 'https://cloud.choozmo.com/test-yt-views',
  47. 'Remark': '',
  48. 'ChooseSubPayment': '',
  49. 'OrderResultURL': '',
  50. 'NeedExtraPaidInfo': 'Y',
  51. 'DeviceSource': '',
  52. 'IgnorePayment': 'ATM#CVS#BARCODE',
  53. 'PlatformID': '',
  54. 'InvoiceMark': 'N',
  55. 'CustomField1': str(ytviews.id),
  56. 'CustomField2': user_data.taxID if user_data.taxID else '',
  57. 'CustomField3': '',
  58. 'CustomField4': '',
  59. 'EncryptType': 1,
  60. 'Language': lang,
  61. }
  62. extend_params_1 = {
  63. 'ExpireDate': 7,
  64. 'PaymentInfoURL': 'https://www.ecpay.com.tw/payment_info_url.php',
  65. 'ClientRedirectURL': '',
  66. }
  67. extend_params_2 = {
  68. 'StoreExpireDate': 15,
  69. 'Desc_1': '',
  70. 'Desc_2': '',
  71. 'Desc_3': '',
  72. 'Desc_4': '',
  73. 'PaymentInfoURL': 'https://www.ecpay.com.tw/payment_info_url.php',
  74. 'ClientRedirectURL': '',
  75. }
  76. extend_params_3 = {
  77. 'BindingCard': 0,
  78. 'MerchantMemberID': '',
  79. }
  80. extend_params_4 = {
  81. 'Redeem': 'N',
  82. 'UnionPay': 0,
  83. }
  84. inv_params = {
  85. # 'RelateNumber': 'Tea0001', # 特店自訂編號
  86. # 'CustomerID': 'TEA_0000001', # 客戶編號
  87. # 'CustomerIdentifier': '53348111', # 統一編號
  88. # 'CustomerName': '客戶名稱',
  89. # 'CustomerAddr': '客戶地址',
  90. # 'CustomerPhone': '0912345678', # 客戶手機號碼
  91. # 'CustomerEmail': 'abc@ecpay.com.tw',
  92. # 'ClearanceMark': '2', # 通關方式
  93. # 'TaxType': '1', # 課稅類別
  94. # 'CarruerType': '', # 載具類別
  95. # 'CarruerNum': '', # 載具編號
  96. # 'Donation': '1', # 捐贈註記
  97. # 'LoveCode': '168001', # 捐贈碼
  98. # 'Print': '1',
  99. # 'InvoiceItemName': '測試商品1|測試商品2',
  100. # 'InvoiceItemCount': '2|3',
  101. # 'InvoiceItemWord': '個|包',
  102. # 'InvoiceItemPrice': '35|10',
  103. # 'InvoiceItemTaxType': '1|1',
  104. # 'InvoiceRemark': '測試商品1的說明|測試商品2的說明',
  105. # 'DelayDay': '0', # 延遲天數
  106. # 'InvType': '07', # 字軌類別
  107. }
  108. # 建立實體
  109. ecpay_payment_sdk = ECPayPaymentSdk(
  110. MerchantID='3002607',
  111. HashKey='pwFHCqoQZGmho4w6',
  112. HashIV='EkRm7iFT261dpevs'
  113. )
  114. # 合併延伸參數
  115. order_params.update(extend_params_1)
  116. order_params.update(extend_params_2)
  117. order_params.update(extend_params_3)
  118. order_params.update(extend_params_4)
  119. # 合併發票參數
  120. order_params.update(inv_params)
  121. try:
  122. # 產生綠界訂單所需參數
  123. final_order_params = ecpay_payment_sdk.create_order(order_params)
  124. # 產生 html 的 form 格式
  125. action_url = 'https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5' # 測試環境
  126. # action_url = 'https://payment.ecpay.com.tw/Cashier/AioCheckOut/V5' # 正式環境
  127. html = ecpay_payment_sdk.gen_html_post_form(action_url, final_order_params)
  128. return html
  129. except Exception as error:
  130. print('An exception happened: ' + str(error))
  131. @router.post('/ytviews-ecpay-payment')
  132. def ecpay_payment(
  133. *,
  134. db: Session = Depends(deps.get_db),
  135. user_data: schemas.YTViewsCreate,
  136. lang: str
  137. ):
  138. print(user_data)
  139. numbers = string.digits
  140. randomNumber = ''.join(choice(numbers) for _ in range(4))
  141. MerchantTradeNo = datetime.now().strftime("%Y%m%d%H%M%SNO")+randomNumber
  142. remark = {'MerchantTradeNo':MerchantTradeNo}
  143. remark_string = json.dump(remark, ensure_ascii=False)
  144. ytviews = crud.ytviews.create_with_payment_data(db,
  145. obj_in=user_data,
  146. epayment='ecpay',
  147. remark=remark_string)
  148. order_params = {
  149. 'MerchantTradeNo': MerchantTradeNo,
  150. 'StoreID': 'SaaS',
  151. 'MerchantTradeDate': datetime.now().strftime("%Y/%m/%d %H:%M:%S"),
  152. 'PaymentType': 'aio',
  153. 'TotalAmount': user_data.amount,
  154. 'TradeDesc': 'YT0.4訂單',
  155. 'ItemName': user_data.item,
  156. 'ReturnURL': 'https://cloud.choozmo.com/api/v1/payment/ytviews-ecpay-result-return',
  157. 'ChoosePayment': 'ALL',
  158. 'ClientBackURL': 'https://cloud.choozmo.com/yt-views',
  159. 'ItemURL': 'https://cloud.choozmo.com/yt-views',
  160. 'Remark': '',
  161. 'ChooseSubPayment': '',
  162. 'OrderResultURL': '',
  163. 'NeedExtraPaidInfo': 'Y',
  164. 'DeviceSource': '',
  165. 'IgnorePayment': 'ATM#CVS#BARCODE',
  166. 'PlatformID': '',
  167. 'InvoiceMark': 'N',
  168. 'CustomField1': str(ytviews.id),
  169. 'CustomField2': user_data.taxID if user_data.taxID else '',
  170. 'CustomField3': '',
  171. 'CustomField4': '',
  172. 'EncryptType': 1,
  173. 'Language': lang,
  174. }
  175. extend_params_1 = {
  176. 'ExpireDate': 7,
  177. 'PaymentInfoURL': 'https://www.ecpay.com.tw/payment_info_url.php',
  178. 'ClientRedirectURL': '',
  179. }
  180. extend_params_2 = {
  181. 'StoreExpireDate': 15,
  182. 'Desc_1': '',
  183. 'Desc_2': '',
  184. 'Desc_3': '',
  185. 'Desc_4': '',
  186. 'PaymentInfoURL': 'https://www.ecpay.com.tw/payment_info_url.php',
  187. 'ClientRedirectURL': '',
  188. }
  189. extend_params_3 = {
  190. 'BindingCard': 0,
  191. 'MerchantMemberID': '',
  192. }
  193. extend_params_4 = {
  194. 'Redeem': 'N',
  195. 'UnionPay': 0,
  196. }
  197. inv_params = {
  198. # 'RelateNumber': 'Tea0001', # 特店自訂編號
  199. # 'CustomerID': 'TEA_0000001', # 客戶編號
  200. # 'CustomerIdentifier': '53348111', # 統一編號
  201. # 'CustomerName': '客戶名稱',
  202. # 'CustomerAddr': '客戶地址',
  203. # 'CustomerPhone': '0912345678', # 客戶手機號碼
  204. # 'CustomerEmail': 'abc@ecpay.com.tw',
  205. # 'ClearanceMark': '2', # 通關方式
  206. # 'TaxType': '1', # 課稅類別
  207. # 'CarruerType': '', # 載具類別
  208. # 'CarruerNum': '', # 載具編號
  209. # 'Donation': '1', # 捐贈註記
  210. # 'LoveCode': '168001', # 捐贈碼
  211. # 'Print': '1',
  212. # 'InvoiceItemName': '測試商品1|測試商品2',
  213. # 'InvoiceItemCount': '2|3',
  214. # 'InvoiceItemWord': '個|包',
  215. # 'InvoiceItemPrice': '35|10',
  216. # 'InvoiceItemTaxType': '1|1',
  217. # 'InvoiceRemark': '測試商品1的說明|測試商品2的說明',
  218. # 'DelayDay': '0', # 延遲天數
  219. # 'InvType': '07', # 字軌類別
  220. }
  221. # 建立實體
  222. ecpay_payment_sdk = ECPayPaymentSdk(
  223. MerchantID='3226141',
  224. HashKey='OhcjDTeXK9PKW9vb',
  225. HashIV='AfOmUM06S0bt8KPE'
  226. )
  227. # 合併延伸參數
  228. order_params.update(extend_params_1)
  229. order_params.update(extend_params_2)
  230. order_params.update(extend_params_3)
  231. order_params.update(extend_params_4)
  232. # 合併發票參數
  233. order_params.update(inv_params)
  234. try:
  235. # 產生綠界訂單所需參數
  236. final_order_params = ecpay_payment_sdk.create_order(order_params)
  237. # 產生 html 的 form 格式
  238. # action_url = 'https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5' # 測試環境
  239. action_url = 'https://payment.ecpay.com.tw/Cashier/AioCheckOut/V5' # 正式環境
  240. html = ecpay_payment_sdk.gen_html_post_form(action_url, final_order_params)
  241. return html
  242. except Exception as error:
  243. print('An exception happened: ' + str(error))
  244. @router.get('/ytviews-list-all', response_model=List[schemas.YTViews])
  245. def get_list(
  246. *,
  247. db: Session = Depends(deps.get_db),
  248. ):
  249. ytviews_list = crud.ytviews.get_multi(db)
  250. return ytviews_list
  251. @router.post("/ytviews-ecpay-result-return")
  252. def ecpay_return(
  253. *,
  254. db: Session = Depends(deps.get_db),
  255. MerchantID: Optional[str]=Form(None),
  256. MerchantTradeNo: Optional[str]=Form(None),
  257. StoreID: Optional[str]=Form(None),
  258. RtnCode: Optional[int]=Form(None),
  259. RtnMsg: Optional[str]=Form(None),
  260. TradeNo: Optional[str]=Form(None),
  261. TradeAmt: Optional[int]=Form(None),
  262. PaymentDate: Optional[str]=Form(None),
  263. PaymentType: Optional[str]=Form(None),
  264. PaymentTypeChargeFee: Optional[int]=Form(None),
  265. TradeDate: Optional[str]=Form(None),
  266. SimulatePaid: Optional[int]=Form(None),
  267. CustomField1: Optional[str]=Form(None),
  268. CustomField2: Optional[str]=Form(None),
  269. CustomField3: Optional[str]=Form(None),
  270. CustomField4: Optional[str]=Form(None),
  271. CheckMacValue: Optional[str]=Form(None),
  272. ) -> Any:
  273. #送email
  274. print(f"\
  275. MerchantID: {MerchantID} \n\
  276. MerchantTradeNo: {MerchantTradeNo}\n\
  277. StoreID: {StoreID}\n\
  278. RtnCode: {RtnCode}\n\
  279. RtnMsg: {RtnMsg}\n\
  280. TradeNo: {TradeNo}\n\
  281. TradeAmt: {TradeAmt}\n\
  282. PaymentDate: {PaymentDate}\n\
  283. PaymentType: {PaymentType}\n\
  284. PaymentTypeChargeFee: {PaymentTypeChargeFee}\n\
  285. TradeDate: {TradeDate}\n\
  286. SimulatePaid: {SimulatePaid}\n\
  287. CustomField1: {CustomField1}\n\
  288. CustomField2: {CustomField2}\n\
  289. CustomField3: {CustomField3}\n\
  290. CustomField4: {CustomField4}\n\
  291. CheckMacValue: {CheckMacValue}\
  292. ")
  293. if RtnCode==1:
  294. ytviews_id = int(CustomField1)
  295. ytviews = crud.ytviews.get(db=db, id=ytviews_id)
  296. remark = json.loads(ytviews.remark)
  297. remark['TradeNo'] = TradeNo
  298. crud.ytviews.update(db, db_obj=ytviews, obj_in={"payment_state":"succeeded", "remark":json.dumps(remark, ensure_ascii=False)})
  299. return Response(content='1', status_code=status.HTTP_200_OK)