payment.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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
  6. from sqlalchemy.orm import Session
  7. from app import crud, models, schemas
  8. from app.api import deps
  9. from app.core.config import settings
  10. from app.core.ecpay_payment_sdk import ECPayPaymentSdk
  11. from app.utils import send_new_account_email
  12. router = APIRouter()
  13. @router.post("/ecpayTestPay", response_model=str)
  14. def ecpay(
  15. *,
  16. db: Session = Depends(deps.get_db),
  17. current_user: models.User = Depends(deps.get_current_active_user),
  18. amount: str=Form(...),
  19. ) -> Any:
  20. print(amount)
  21. order_params = {
  22. 'MerchantTradeNo': datetime.now().strftime("NO%Y%m%d%H%M%S"),
  23. 'StoreID': '3226141',
  24. 'MerchantTradeDate': datetime.now().strftime("%Y/%m/%d %H:%M:%S"),
  25. 'PaymentType': 'aio',
  26. 'TotalAmount': amount,
  27. 'TradeDesc': '訂單測試',
  28. 'ItemName': '商品1#商品2',
  29. 'ReturnURL': 'https://cloud.choozmo.com/api/v1/payment/ecpayTestReturn',
  30. 'ChoosePayment': 'ALL',
  31. 'ClientBackURL': 'http://dev.cloud.choozmo.com:5173/main/admin/test-ecpay',
  32. 'ItemURL': 'http://dev.cloud.choozmo.com:5173/main/admin/test-ecpay',
  33. 'Remark': '交易備註',
  34. 'ChooseSubPayment': '',
  35. 'OrderResultURL': 'http://dev.cloud.choozmo.com:5173/main/admin/test-ecpay',
  36. 'NeedExtraPaidInfo': 'Y',
  37. 'DeviceSource': '',
  38. 'IgnorePayment': '',
  39. 'PlatformID': '',
  40. 'InvoiceMark': 'N',
  41. 'CustomField1': '',
  42. 'CustomField2': '',
  43. 'CustomField3': '',
  44. 'CustomField4': '',
  45. 'EncryptType': 1,
  46. 'Language': '',
  47. }
  48. extend_params_1 = {
  49. 'ExpireDate': 7,
  50. 'PaymentInfoURL': 'https://www.ecpay.com.tw/payment_info_url.php',
  51. 'ClientRedirectURL': '',
  52. }
  53. extend_params_2 = {
  54. 'StoreExpireDate': 15,
  55. 'Desc_1': '',
  56. 'Desc_2': '',
  57. 'Desc_3': '',
  58. 'Desc_4': '',
  59. 'PaymentInfoURL': 'https://www.ecpay.com.tw/payment_info_url.php',
  60. 'ClientRedirectURL': '',
  61. }
  62. extend_params_3 = {
  63. 'BindingCard': 0,
  64. 'MerchantMemberID': '',
  65. }
  66. extend_params_4 = {
  67. 'Redeem': 'N',
  68. 'UnionPay': 0,
  69. }
  70. inv_params = {
  71. # 'RelateNumber': 'Tea0001', # 特店自訂編號
  72. # 'CustomerID': 'TEA_0000001', # 客戶編號
  73. # 'CustomerIdentifier': '53348111', # 統一編號
  74. # 'CustomerName': '客戶名稱',
  75. # 'CustomerAddr': '客戶地址',
  76. # 'CustomerPhone': '0912345678', # 客戶手機號碼
  77. # 'CustomerEmail': 'abc@ecpay.com.tw',
  78. # 'ClearanceMark': '2', # 通關方式
  79. # 'TaxType': '1', # 課稅類別
  80. # 'CarruerType': '', # 載具類別
  81. # 'CarruerNum': '', # 載具編號
  82. # 'Donation': '1', # 捐贈註記
  83. # 'LoveCode': '168001', # 捐贈碼
  84. # 'Print': '1',
  85. # 'InvoiceItemName': '測試商品1|測試商品2',
  86. # 'InvoiceItemCount': '2|3',
  87. # 'InvoiceItemWord': '個|包',
  88. # 'InvoiceItemPrice': '35|10',
  89. # 'InvoiceItemTaxType': '1|1',
  90. # 'InvoiceRemark': '測試商品1的說明|測試商品2的說明',
  91. # 'DelayDay': '0', # 延遲天數
  92. # 'InvType': '07', # 字軌類別
  93. }
  94. # 建立實體
  95. ecpay_payment_sdk = ECPayPaymentSdk(
  96. MerchantID='3002607',
  97. HashKey='pwFHCqoQZGmho4w6',
  98. HashIV='EkRm7iFT261dpevs'
  99. )
  100. # 合併延伸參數
  101. order_params.update(extend_params_1)
  102. order_params.update(extend_params_2)
  103. order_params.update(extend_params_3)
  104. order_params.update(extend_params_4)
  105. # 合併發票參數
  106. order_params.update(inv_params)
  107. try:
  108. # 產生綠界訂單所需參數
  109. final_order_params = ecpay_payment_sdk.create_order(order_params)
  110. # 產生 html 的 form 格式
  111. action_url = 'https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5' # 測試環境
  112. # action_url = 'https://payment.ecpay.com.tw/Cashier/AioCheckOut/V5' # 正式環境
  113. html = ecpay_payment_sdk.gen_html_post_form(action_url, final_order_params)
  114. print(html)
  115. return html
  116. except Exception as error:
  117. print('An exception happened: ' + str(error))
  118. @router.post("/ecpayTestReturn")
  119. def ecpay_return(
  120. *,
  121. MerchantID: Optional[str]=Form(None),
  122. MerchantTradeNo: Optional[str]=Form(None),
  123. StoreID: Optional[str]=Form(None),
  124. RtnCode: Optional[int]=Form(None),
  125. RtnMsg: Optional[str]=Form(None),
  126. TradeNo: Optional[str]=Form(None),
  127. TradeAmt: Optional[int]=Form(None),
  128. PaymentDate: Optional[str]=Form(None),
  129. PaymentType: Optional[str]=Form(None),
  130. PaymentTypeChargeFee: Optional[int]=Form(None),
  131. TradeDate: Optional[str]=Form(None),
  132. SimulatePaid: Optional[int]=Form(None),
  133. CustomField1: Optional[str]=Form(None),
  134. CustomField2: Optional[str]=Form(None),
  135. CustomField3: Optional[str]=Form(None),
  136. CustomField4: Optional[str]=Form(None),
  137. CheckMacValue: Optional[str]=Form(None),
  138. ) -> Any:
  139. print(f"\
  140. MerchantID: {MerchantID} \n\
  141. MerchantTradeNo: {MerchantTradeNo}\n\
  142. StoreID: {StoreID}\n\
  143. RtnCode: {RtnCode}\n\
  144. RtnMsg: {RtnMsg}\n\
  145. TradeNo: {TradeNo}\n\
  146. TradeAmt: {TradeAmt}\n\
  147. PaymentDate: {PaymentDate}\n\
  148. PaymentType: {PaymentType}\n\
  149. PaymentTypeChargeFee: {PaymentTypeChargeFee}\n\
  150. TradeDate: {TradeDate}\n\
  151. SimulatePaid: {SimulatePaid}\n\
  152. CustomField1: {CustomField1}\n\
  153. CustomField2: {CustomField2}\n\
  154. CustomField3: {CustomField3}\n\
  155. CustomField4: {CustomField4}\n\
  156. CheckMacValue: {CheckMacValue}\
  157. ")
  158. return Response(content='1', status_code=status.HTTP_200_OK)