pay.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. package toppay
  2. import (
  3. "encoding/base64"
  4. "encoding/json"
  5. "fmt"
  6. "math"
  7. "net/http"
  8. "net/url"
  9. "strconv"
  10. "strings"
  11. "time"
  12. "bet24.com/servers/payment/shop"
  13. "bet24.com/log"
  14. "bet24.com/public"
  15. "bet24.com/servers/payment/config"
  16. "bet24.com/servers/payment/db"
  17. "github.com/gin-gonic/gin"
  18. )
  19. // 下单
  20. func PayOrder(c *gin.Context) {
  21. obj := db.NewOrder(db.SP_Kaya_ORDER)
  22. if err := c.ShouldBind(&obj.In); err != nil {
  23. log.Debug("%s query params err %v", "toppay.PayOrder", err)
  24. c.String(http.StatusOK, "")
  25. return
  26. }
  27. obj.In.IpAddress = strings.Split(c.Request.RemoteAddr, ":")[0]
  28. //// 币种为空,根据ip获取
  29. //if obj.In.Currency == "" {
  30. // currency := shop.GetCurrencyRateByIp(obj.In.UserID, obj.In.IpAddress)
  31. // obj.In.Currency = currency
  32. //}
  33. // 获取产品信息
  34. item := shop.GetProduct(obj.In.ProductID)
  35. if item == nil {
  36. log.Error("%s query GetProduct productId=%s currency=%s is nil", "toppay.PayOrder", obj.In.ProductID, obj.In.Currency)
  37. c.String(http.StatusOK, "")
  38. return
  39. }
  40. //// 获取当前汇率信息
  41. //info := shop.GetExchangeRate(obj.In.Currency)
  42. //if info == nil {
  43. // log.Error("%s query GetExchangeRate obj.In.Currency=%s is nil", "toppay.PayOrder", obj.In.Currency)
  44. // c.String(http.StatusOK, "")
  45. // return
  46. //}
  47. //
  48. //// 计算价格
  49. //calPrice := info.Rate * item.Price
  50. //
  51. //// 检查价格是否篡改
  52. //if calPrice != obj.In.Price {
  53. // log.Error("%s obj.In.Price=%v info.Rate=%v calPrice=%v is invalid", "toppay.PayOrder", obj.In.Price, info.Rate, calPrice)
  54. // c.String(http.StatusOK, "")
  55. // return
  56. //}
  57. // 检查价格是否篡改
  58. if item.Price != obj.In.Price {
  59. log.Error("%s obj.In.Price=%v calPrice=%v is invalid", "toppay.PayOrder", obj.In.Price, item.Price)
  60. c.String(http.StatusOK, "")
  61. return
  62. }
  63. obj.DoAction(nil)
  64. if obj.Out.OrderID == "" {
  65. log.Debug("%s GenOrder fail obj.In=%+v", "toppay.PayOrder", obj.In)
  66. c.String(http.StatusOK, "")
  67. return
  68. }
  69. // 请求payOrder的代码
  70. req := pay_req{
  71. MerchantCode: config.Server.TopPay.MerchantCode,
  72. Method: "", // DANA
  73. OrderNum: obj.Out.OrderID,
  74. PayMoney: int(math.Ceil(obj.In.Price)),
  75. ProductDetail: obj.In.ProductID,
  76. Name: strconv.Itoa(obj.In.UserID),
  77. // Name: obj.In.Name,
  78. Email: obj.In.Email,
  79. Phone: obj.In.Tel,
  80. NotifyUrl: config.Server.TopPay.Url_pay_notify,
  81. ExpiryPeriod: 30,
  82. DateTime: time.Now().Format(TIME_FORMAT),
  83. }
  84. params := url.Values{}
  85. params.Set("merchantCode", req.MerchantCode)
  86. params.Set("method", req.Method)
  87. params.Set("orderNum", req.OrderNum)
  88. params.Set("payMoney", strconv.Itoa(req.PayMoney))
  89. params.Set("productDetail", req.ProductDetail)
  90. params.Set("name", req.Name)
  91. params.Set("email", req.Email)
  92. params.Set("phone", req.Phone)
  93. params.Set("notifyUrl", req.NotifyUrl)
  94. params.Set("expiryPeriod", strconv.Itoa(req.ExpiryPeriod))
  95. params.Set("dateTime", req.DateTime)
  96. // 生成签名
  97. checkContent := createEncryptStr(params)
  98. // log.Debug("order.checkContent ==> %s", checkContent)
  99. // 商户请求我们接口时使用商户私钥对请求参数 进行加密
  100. mchPriKey := fmt.Sprintf(`-----BEGIN PRIVATE KEY-----
  101. %s
  102. -----END PRIVATE KEY-----
  103. `, config.Server.TopPay.MCH_PRIVATE_KEY)
  104. if err := public.RSA.SetPrivateKey(mchPriKey); err != nil {
  105. log.Error("toppay.payOrder set private key :%v ==> %+v", err, params)
  106. return
  107. }
  108. // 私钥加密
  109. prienctypt, err := public.RSA.PriKeyENCTYPT([]byte(checkContent))
  110. if err != nil {
  111. log.Error("toppay.payOrder RSA.PriKeyENCTYPT err %v", err)
  112. return
  113. }
  114. req.Sign = base64.StdEncoding.EncodeToString(prienctypt)
  115. // log.Debug("kaya.payOrder req ==> %+v ", params)
  116. // POST请求
  117. buf, _ := json.Marshal(req)
  118. respBody := public.HttpPostByJson(config.Server.TopPay.Url_pay_order, string(buf))
  119. log.Debug("toppay.payOrder req ==> %+v resp ==> %+v", params, respBody)
  120. var resp pay_resp
  121. if err := json.Unmarshal([]byte(respBody), &resp); err != nil {
  122. log.Error("toppay.payOrder json unmarshal req ==> %+v resp ==> %+v fail %v", params, respBody, err)
  123. return
  124. }
  125. // log.Debug("kaya.payOrder resp ==> %+v", resp)
  126. // 请求响应码,00000表示成功,其他失败
  127. if resp.PlatRespCode != RESP_CODE_SUCCESS {
  128. log.Error("toppay.payOrder post return resp fail ==> %+v", resp)
  129. return
  130. }
  131. // 跳转到支付页面,以便持卡人完成支付过程
  132. c.Redirect(http.StatusMovedPermanently, resp.Url)
  133. // c.String(http.StatusOK, "Success")
  134. return
  135. }
  136. // 回调通知
  137. func PayNotify(c *gin.Context) {
  138. var resp payNotify
  139. if err := c.ShouldBind(&resp); err != nil {
  140. log.Debug("%s query params err %v", "toppay.PayNotify", err)
  141. c.String(http.StatusOK, "")
  142. return
  143. }
  144. log.Debug("toppay.PayNotify resp ==> %+v", resp)
  145. params := url.Values{}
  146. params.Set("code", resp.Code)
  147. params.Set("email", resp.Email)
  148. params.Set("method", resp.Method)
  149. params.Set("msg", resp.Msg)
  150. params.Set("name", resp.Name)
  151. params.Set("orderNum", resp.OrderNum)
  152. params.Set("payFee", strconv.Itoa(resp.PayFee))
  153. params.Set("payMoney", strconv.Itoa(resp.PayMoney))
  154. params.Set("platOrderNum", resp.PlatOrderNum)
  155. params.Set("vaNumber", resp.VaNumber)
  156. // 生成签名
  157. checkContent := createEncryptStr(params)
  158. // log.Debug("kaya.PayNotify checkContent ==> %s", checkContent)
  159. // 商户使用 商户后台显示的平台公钥 进行解密
  160. platPubKey := fmt.Sprintf(`-----BEGIN PUBLIC KEY-----
  161. %s
  162. -----END PUBLIC KEY-----
  163. `, config.Server.TopPay.PLAT_PUBLIC_KEY)
  164. if err := public.RSA.SetPublicKey(platPubKey); err != nil {
  165. log.Error("toppay.PayNotify set public key :%v ==> %+v", err, params)
  166. return
  167. }
  168. data, err := base64.StdEncoding.DecodeString(resp.PlatSign)
  169. if err != nil {
  170. log.Error("toppay.PayNotify base64.StdEncoding.DecodeString err %v", err)
  171. return
  172. }
  173. // 公钥解密
  174. pubdecrypt, err := public.RSA.PubKeyDECRYPT(data)
  175. if err != nil {
  176. log.Error("toppay.PayNotify RSA.PubKeyDECRYPT err %v", err)
  177. return
  178. }
  179. if checkContent != string(pubdecrypt) {
  180. log.Error("toppay.PayNotify 签名失败 ==> %+v", resp)
  181. return
  182. }
  183. log.Debug("toppay.PayNotify 签名成功")
  184. // 0-成功,其他失败
  185. if resp.Code != "00" {
  186. log.Error("toppay.PayNotify resp ==> %+v 失败", resp)
  187. return
  188. }
  189. // 数据库操作
  190. obj := db.NewNotify(db.SP_Kaya_NOTIFY)
  191. obj.In.OrderID = resp.OrderNum
  192. obj.In.TradeID = resp.PlatOrderNum
  193. //obj.In.Price = resp.PayMoney
  194. obj.DoAction(nil)
  195. // 操作成功,给道具
  196. // if obj.Out.RetCode == 1 {
  197. // // 充值
  198. // resp := coreClient.Recharge(obj.Out.UserID, obj.Out.ProductID)
  199. // log.Debug("%s 充值成功 %+v", "toppay.PayNotify", resp)
  200. // }
  201. c.String(http.StatusOK, "success")
  202. return
  203. }