pay.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. package kaya
  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. coreClient "bet24.com/servers/coreservice/client"
  16. "bet24.com/servers/payment/config"
  17. "bet24.com/servers/payment/db"
  18. "github.com/gin-gonic/gin"
  19. )
  20. // 下单
  21. func PayOrder(c *gin.Context) {
  22. obj := db.NewOrder(db.SP_Kaya_ORDER)
  23. if err := c.ShouldBind(&obj.In); err != nil {
  24. log.Debug("%s query params err %v", "kaya.PayOrder", 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", "kaya.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", "kaya.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", "kaya.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", "kaya.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", "kaya.PayOrder", obj.In)
  67. c.String(http.StatusOK, "")
  68. return
  69. }
  70. //请求payOrder的代码
  71. req := pay_req{
  72. MerchantCode: config.Server.KayaPay.MerchantCode,
  73. Method: "BT",
  74. OrderNum: obj.Out.OrderID,
  75. PayMoney: int(math.Ceil(obj.In.Price)),
  76. ProductDetail: obj.In.ProductID,
  77. Name: obj.In.Name,
  78. Email: obj.In.Email,
  79. Phone: obj.In.Tel,
  80. NotifyUrl: config.Server.KayaPay.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.KayaPay.MCH_PRIVATE_KEY)
  104. if err := public.RSA.SetPrivateKey(mchPriKey); err != nil {
  105. log.Error("kaya.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("kaya.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.KayaPay.Url_pay_order, string(buf))
  119. log.Debug("kaya.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("kaya.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("kaya.payOrder post return resp fail ==> %+v", resp)
  129. return
  130. }
  131. c.String(http.StatusOK, "Success")
  132. return
  133. }
  134. // 回调通知
  135. func PayNotify(c *gin.Context) {
  136. var resp payNotify
  137. if err := c.ShouldBind(&resp); err != nil {
  138. log.Debug("%s query params err %v", "kaya.PayNotify", err)
  139. c.String(http.StatusOK, "")
  140. return
  141. }
  142. log.Debug("kaya.PayNotify resp ==> %+v", resp)
  143. params := url.Values{}
  144. params.Set("code", resp.Code)
  145. params.Set("email", resp.Email)
  146. params.Set("method", resp.Method)
  147. params.Set("msg", resp.Msg)
  148. params.Set("name", resp.Name)
  149. params.Set("orderNum", resp.OrderNum)
  150. params.Set("payFee", strconv.Itoa(resp.PayFee))
  151. params.Set("payMoney", strconv.Itoa(resp.PayMoney))
  152. params.Set("platOrderNum", resp.PlatOrderNum)
  153. params.Set("vaNumber", resp.VaNumber)
  154. // 生成签名
  155. checkContent := createEncryptStr(params)
  156. // log.Debug("kaya.PayNotify checkContent ==> %s", checkContent)
  157. // 商户使用 商户后台显示的平台公钥 进行解密
  158. platPubKey := fmt.Sprintf(`-----BEGIN PUBLIC KEY-----
  159. %s
  160. -----END PUBLIC KEY-----
  161. `, config.Server.KayaPay.PLAT_PUBLIC_KEY)
  162. if err := public.RSA.SetPublicKey(platPubKey); err != nil {
  163. log.Error("kaya.PayNotify set public key :%v ==> %+v", err, params)
  164. return
  165. }
  166. data, err := base64.StdEncoding.DecodeString(resp.PlatSign)
  167. if err != nil {
  168. log.Error("kaya.PayNotify base64.StdEncoding.DecodeString err %v", err)
  169. return
  170. }
  171. // 公钥解密
  172. pubdecrypt, err := public.RSA.PubKeyDECRYPT(data)
  173. if err != nil {
  174. log.Error("kaya.PayNotify RSA.PubKeyDECRYPT err %v", err)
  175. return
  176. }
  177. if checkContent != string(pubdecrypt) {
  178. log.Error("kaya.PayNotify 签名失败 ==> %+v", resp)
  179. return
  180. }
  181. log.Debug("kaya.PayNotify 签名成功")
  182. // 0-成功,其他失败
  183. if resp.Code != "00" {
  184. log.Error("kaya.PayNotify resp ==> %+v 失败", resp)
  185. return
  186. }
  187. // 数据库操作
  188. obj := db.NewNotify(db.SP_Kaya_NOTIFY)
  189. obj.In.OrderID = resp.OrderNum
  190. obj.In.TradeID = resp.PlatOrderNum
  191. //obj.In.Price = resp.PayMoney
  192. obj.DoAction(nil)
  193. //操作成功,给道具
  194. if obj.Out.RetCode == 1 {
  195. //充值
  196. resp := coreClient.Recharge(obj.Out.UserID, obj.Out.ProductID)
  197. log.Debug("%s 充值成功 %+v", "kaya.PayNotify", resp)
  198. }
  199. c.String(http.StatusOK, "success")
  200. return
  201. }