control.go 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. package cropay
  2. import (
  3. "encoding/base64"
  4. "encoding/xml"
  5. "fmt"
  6. "net/http"
  7. "net/url"
  8. "strconv"
  9. "strings"
  10. "time"
  11. "bet24.com/servers/payment/shop"
  12. "bet24.com/log"
  13. "bet24.com/public"
  14. coreClient "bet24.com/servers/coreservice/client"
  15. "bet24.com/servers/payment/config"
  16. "bet24.com/servers/payment/db"
  17. "github.com/gin-gonic/gin"
  18. uuid "github.com/satori/go.uuid"
  19. )
  20. // 下单
  21. func Order(c *gin.Context) {
  22. obj := db.NewOrder(db.SP_CRO_ORDER)
  23. if err := c.ShouldBind(&obj.In); err != nil {
  24. log.Debug("%s query params err %v", "cropay.Order", err)
  25. c.String(http.StatusOK, "")
  26. return
  27. }
  28. obj.In.IpAddress = strings.Split(c.Request.RemoteAddr, ":")[0]
  29. //// 币种为空,根据ip获取
  30. //if obj.In.Currency == "" {
  31. // currency := shop.GetCurrencyRateByIp(obj.In.UserID, obj.In.IpAddress)
  32. // obj.In.Currency = currency
  33. //}
  34. // 获取产品信息
  35. item := shop.GetProduct(obj.In.ProductID)
  36. if item == nil {
  37. log.Error("%s query GetProduct productId=%s currency=%s is nil", "cropay.PayOrder", obj.In.ProductID, obj.In.Currency)
  38. c.String(http.StatusOK, "")
  39. return
  40. }
  41. //// 获取当前汇率信息
  42. //info := shop.GetExchangeRate(obj.In.Currency)
  43. //if info == nil {
  44. // log.Error("%s query GetExchangeRate obj.In.Currency=%s is nil", "cropay.PayOrder", obj.In.Currency)
  45. // c.String(http.StatusOK, "")
  46. // return
  47. //}
  48. //
  49. //// 计算价格
  50. //calPrice := info.Rate * item.Price
  51. //
  52. //// 检查价格是否篡改
  53. //if calPrice != obj.In.Price {
  54. // log.Error("%s obj.In.Price=%v info.Rate=%v calPrice=%v is invalid", "cropay.PayOrder", obj.In.Price, info.Rate, calPrice)
  55. // c.String(http.StatusOK, "")
  56. // return
  57. //}
  58. // 检查价格是否篡改
  59. if item.Price != obj.In.Price {
  60. log.Error("%s obj.In.Price=%v calPrice=%v is invalid", "cropay.PayOrder", obj.In.Price, item.Price)
  61. c.String(http.StatusOK, "")
  62. return
  63. }
  64. obj.DoAction(nil)
  65. if obj.Out.OrderID == "" {
  66. log.Debug("%s GenOrder fail obj.In=%+v", "cropay.Order", obj.In)
  67. c.String(http.StatusOK, "")
  68. return
  69. }
  70. id, _ := uuid.NewV4()
  71. order_hash := config.Server.Cropay.Order_hash
  72. merchant_id := config.Server.Cropay.Merchant_id
  73. merch_order_id := obj.Out.OrderID
  74. price_currency := "IDR"
  75. price_amount := obj.In.Price
  76. //order_hash + merchant_id + merch_order_id + price_currency + price_amount
  77. checkContent := order_hash + strconv.Itoa(merchant_id) + merch_order_id + price_currency +
  78. strconv.FormatFloat(price_amount, 'f', -1, 64)
  79. log.Debug("order.checkContent ==> %s", checkContent)
  80. signature := public.GetMd5String(checkContent)
  81. //请求payOrder的代码
  82. req := payOrder_req{
  83. baseInfo: baseInfo{
  84. Merchant_id: merchant_id,
  85. Order_type: "5",
  86. Gw_version: "go(1.0)",
  87. Language: "",
  88. Merch_order_ori_id: obj.Out.OrderID,
  89. Merch_order_id: obj.Out.OrderID,
  90. Merch_order_date: time.Now().Format("20060102150405"),
  91. Price_currency: price_currency,
  92. Price_amount: price_amount,
  93. Ip: obj.In.IpAddress,
  94. Url_sync: config.Server.Cropay.Url_sync,
  95. Url_succ_back: config.Server.Cropay.Url_succ_back,
  96. Url_fail_back: config.Server.Cropay.Url_fail_back,
  97. Url_referrer_domain: config.Server.Cropay.Url_referrer_domain,
  98. },
  99. billInfo: billInfo{
  100. Bill_address: "",
  101. Bill_country: "",
  102. Bill_province: "",
  103. Bill_city: "",
  104. Bill_email: obj.In.Email,
  105. Bill_phone: obj.In.Tel,
  106. Bill_post: "",
  107. },
  108. deliveryInfo: deliveryInfo{
  109. Delivery_name: obj.In.Name,
  110. Delivery_address: "",
  111. Delivery_country: "",
  112. Delivery_province: "",
  113. Delivery_city: "",
  114. Delivery_email: obj.In.Email,
  115. Delivery_phone: obj.In.Tel,
  116. Delivery_post: "",
  117. },
  118. productInfo: productInfo{
  119. Product_name: "Recharge",
  120. Product_sn: obj.In.ProductID,
  121. Quantity: 1,
  122. Unit: obj.In.Price,
  123. },
  124. Signature: signature,
  125. Client_finger_cybs: id.String(),
  126. }
  127. params := url.Values{}
  128. params.Set("merchant_id", strconv.Itoa(config.Server.Cropay.Merchant_id*818+5201314))
  129. params.Set("order_type", req.Order_type)
  130. params.Set("gw_version", req.Gw_version)
  131. params.Set("language", req.Language)
  132. params.Set("merch_order_ori_id", req.Merch_order_ori_id)
  133. params.Set("merch_order_id", req.Merch_order_id)
  134. params.Set("merch_order_date", req.Merch_order_date)
  135. params.Set("price_currency", req.Price_currency)
  136. params.Set("price_amount", strconv.FormatFloat(req.Price_amount, 'f', -1, 64))
  137. params.Set("ip", req.Ip)
  138. params.Set("url_sync", req.Url_sync)
  139. params.Set("url_succ_back", req.Url_succ_back)
  140. params.Set("url_fail_back", req.Url_fail_back)
  141. params.Set("url_referrer_domain", req.Url_referrer_domain)
  142. params.Set("bill_address", req.Bill_address)
  143. params.Set("bill_country", req.Bill_country)
  144. params.Set("bill_province", req.Bill_province)
  145. params.Set("bill_city", req.Bill_city)
  146. params.Set("bill_email", req.Bill_email)
  147. params.Set("bill_phone", req.Bill_phone)
  148. params.Set("bill_post", req.Bill_post)
  149. params.Set("delivery_name", req.Delivery_name)
  150. params.Set("delivery_address", req.Delivery_address)
  151. params.Set("delivery_country", req.Delivery_country)
  152. params.Set("delivery_province", req.Delivery_province)
  153. params.Set("delivery_city", req.Delivery_city)
  154. params.Set("delivery_email", req.Delivery_email)
  155. params.Set("delivery_phone", req.Delivery_phone)
  156. params.Set("delivery_post", req.Delivery_post)
  157. params.Set("product_name", req.Product_name)
  158. params.Set("product_sn", req.Product_sn)
  159. params.Set("quantity", strconv.Itoa(req.Quantity))
  160. params.Set("unit", strconv.FormatFloat(req.Unit, 'f', -1, 64))
  161. params.Set("signature", req.Signature)
  162. params.Set("client_finger_cybs", req.Client_finger_cybs)
  163. respBody := public.HttpPostForm(config.Server.Cropay.Url_pay_order, params)
  164. log.Debug("cropay.payOrder req ==> %+v resp ==> %+v", params, respBody)
  165. var resp payOrder_resp
  166. if err := xml.Unmarshal([]byte(respBody), &resp); err != nil {
  167. log.Error("cropay xml unmarshal req ==> %+v resp ==> %+v fail %v", params, respBody, err)
  168. return
  169. }
  170. log.Debug("cropay.payOrder resp ==> %+v", resp)
  171. //md5(order_hash+merchant_id+merch_order_id+price_currency+price_amount+order_id+status)
  172. checkContent_resp := config.Server.Cropay.Order_hash +
  173. strconv.Itoa(resp.Merchant_id) + resp.Merch_order_id + resp.Price_currency +
  174. strconv.FormatFloat(resp.Price_amount, 'f', -1, 64) +
  175. resp.Order_id + resp.Status
  176. // 生成签名
  177. signature_resp := public.GetMd5String(checkContent_resp)
  178. if resp.Signature != signature_resp {
  179. log.Error("cropay.payOrder 签名失败 post return resp ==> %+v", resp)
  180. return
  181. }
  182. log.Debug("cropay.payOrder 签名成功")
  183. // 待处理状态
  184. if resp.Status != "T" {
  185. log.Error("cropay.payOrder post return resp fail ==> %+v", resp)
  186. c.JSON(http.StatusOK, struct {
  187. Status string `json:"status"`
  188. Message string `json:"message"`
  189. Merch_order_id string `json:"merch_order_id"`
  190. Order_id string `json:"order_id"`
  191. Price_currency string `json:"price_currency"`
  192. Price_amount float64 `json:"price_amount"`
  193. }{
  194. Status: resp.Status,
  195. Message: resp.Message,
  196. Merch_order_id: req.Merch_order_id,
  197. Order_id: resp.Order_id,
  198. Price_currency: resp.Price_currency,
  199. Price_amount: resp.Price_amount,
  200. })
  201. return
  202. }
  203. paymentUrl, err := base64.StdEncoding.DecodeString(resp.Payment_url)
  204. if err != nil {
  205. log.Error("cropay.payOrder response Payment_url DecodeString fail %v", err)
  206. return
  207. }
  208. log.Debug("paymentUrl ==> %s", string(paymentUrl))
  209. // 跳转到支付页面,以便持卡人完成支付过程
  210. c.Redirect(http.StatusMovedPermanently, string(paymentUrl))
  211. return
  212. }
  213. // 回调通知
  214. func Notify(c *gin.Context) {
  215. var resp notify_resp
  216. if err := c.ShouldBind(&resp); err != nil {
  217. log.Debug("%s query params err %v", "cropay.Notify", err)
  218. c.String(http.StatusOK, "")
  219. return
  220. }
  221. log.Debug("cropay.Notify resp ==> %+v", resp)
  222. // order_hash+merchant_id+merch_order_id+price_currency+price_amount+order_id+status
  223. checkContent := config.Server.Cropay.Order_hash + strconv.Itoa(resp.Merchant_id) +
  224. resp.Merch_order_id + resp.Price_currency + resp.Price_amount + resp.Order_id + resp.Status
  225. signature := public.GetMd5String(checkContent)
  226. if resp.Signature != signature {
  227. log.Error("cropay.Notify 签名失败 resp ==> %+v", resp)
  228. c.String(http.StatusOK, "")
  229. c.Redirect(http.StatusMovedPermanently, config.Server.Cropay.Url_resultPay)
  230. return
  231. }
  232. log.Debug("cropay.Notify 签名成功")
  233. if resp.Status != "Y" {
  234. log.Error("cropay.Notify resp ==> %+v 失败", resp)
  235. c.Redirect(http.StatusMovedPermanently, config.Server.Cropay.Url_resultPay)
  236. return
  237. }
  238. //price, err := strconv.Atoi(strings.ReplaceAll(resp.Price_amount, ".00", ""))
  239. //if err != nil {
  240. // log.Error("cropay.Notify price_amount format err %v", err)
  241. // c.Redirect(http.StatusMovedPermanently, config.Server.Cropay.Url_resultPay)
  242. // return
  243. //}
  244. // 数据库操作
  245. obj := db.NewNotify(db.SP_CRO_NOTIFY)
  246. obj.In.OrderID = resp.Merch_order_id
  247. obj.In.TradeID = resp.Order_id
  248. //obj.In.Price = price
  249. obj.DoAction(nil)
  250. //操作成功,给道具
  251. if obj.Out.RetCode == 1 {
  252. //充值
  253. resp := coreClient.Recharge(obj.Out.UserID, obj.Out.ProductID)
  254. log.Debug("%s 充值成功 %+v", "cropay.Notify", resp)
  255. }
  256. c.String(http.StatusOK, "ISRESPONSION")
  257. c.Redirect(http.StatusMovedPermanently, fmt.Sprintf("%s?code=%d&order=%s",
  258. config.Server.Cropay.Url_resultPay, obj.Out.RetCode, resp.Order_id))
  259. return
  260. }
  261. // 成功回调
  262. func Succ(c *gin.Context) {
  263. var resp notify_resp
  264. if err := c.ShouldBind(&resp); err != nil {
  265. log.Debug("%s query params err %v", "cropay.Succ", err)
  266. c.String(http.StatusOK, "")
  267. return
  268. }
  269. log.Debug("cropay.Succ resp ==> %+v", resp)
  270. c.Redirect(http.StatusMovedPermanently, fmt.Sprintf("%s?code=%d&order=%s",
  271. config.Server.Cropay.Url_resultPay, 1, resp.Order_id))
  272. }
  273. // 失败回调
  274. func Fail(c *gin.Context) {
  275. var resp notify_resp
  276. if err := c.ShouldBind(&resp); err != nil {
  277. log.Debug("%s query params err %v", "cropay.Fail", err)
  278. c.String(http.StatusOK, "")
  279. return
  280. }
  281. log.Debug("cropay.Fail resp ==> %+v", resp)
  282. c.Redirect(http.StatusMovedPermanently, config.Server.Cropay.Url_resultPay)
  283. }