pay.go 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. package lapay
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "math/rand"
  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. )
  19. // 下单
  20. func PayOrder(c *gin.Context) {
  21. obj := db.NewOrder(db.SP_LaPay_ORDER)
  22. if err := c.ShouldBind(&obj.In); err != nil {
  23. log.Debug("%s query params err %v", "laPay.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", "lapay.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", "lapay.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", "lapay.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", "lapay.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", "laPay.PayOrder", obj.In)
  66. c.String(http.StatusOK, "")
  67. return
  68. }
  69. t := strconv.Itoa(int(time.Now().UnixNano() / 1e6))
  70. obj.In.Name = returnDefaultVal(obj.In.Name, public.RandStr(12))
  71. out := inputParameter{
  72. OrderID: obj.Out.OrderID,
  73. PayModel: obj.In.PayModel,
  74. Price: obj.In.Price,
  75. Tel: obj.In.Tel,
  76. Country: obj.In.Country,
  77. Email: obj.In.Email,
  78. Name: obj.In.Name,
  79. CardNum: obj.In.CardNum,
  80. IpAddress: obj.In.IpAddress,
  81. Currency: obj.In.Currency,
  82. T: t,
  83. }
  84. params := url.Values{}
  85. var err error
  86. //if out.PayModel == PAY_MODEL {
  87. // err = walletMode(params, out)
  88. //} else {
  89. out.PayModel = PAY_MODEL2
  90. err = bankcardMode(params, out)
  91. //}
  92. if err != nil {
  93. return
  94. }
  95. respBody := public.HttpPostForm(config.Server.LaPay.UrlPayOrder, params)
  96. log.Debug("laPay.PayOrder post respBody ==> %+v", respBody)
  97. var resp respApiReturn
  98. if err := json.Unmarshal([]byte(respBody), &resp); err != nil {
  99. log.Error("laPay.PayOrder json unmarshal req ==> %+v resp ==> %+v fail %v", params, respBody, err)
  100. return
  101. }
  102. // 返回码,’0000’代表成功
  103. if resp.Meta.Code != "0000" {
  104. log.Error("laPay.PayOrder post return resp fail ==> %+v params ==> %+v", resp, params)
  105. return
  106. }
  107. // 跳转到支付页面,以便持卡人完成支付过程
  108. if resp.Data.WebUrl != "" {
  109. c.Redirect(http.StatusMovedPermanently, resp.Data.WebUrl)
  110. return
  111. }
  112. c.Redirect(http.StatusMovedPermanently, config.Server.LaPay.CallbackUrl)
  113. return
  114. }
  115. // 返回默认值
  116. func returnDefaultVal(val, randStr string) string {
  117. if val == "" {
  118. return randStr
  119. }
  120. return val
  121. }
  122. // todo 后续有新增直接复制银行卡模式的数据进行调整
  123. // 钱包模式
  124. //func walletMode(params url.Values, out inputParameter) error {
  125. // return nil
  126. //}
  127. // 银行卡模式
  128. func bankcardMode(params url.Values, out inputParameter) error {
  129. params.Add("merchantNo", config.Server.LaPay.MerchantNo)
  130. params.Add("timeStamp", out.T)
  131. params.Add("merchantOrderNo", out.OrderID)
  132. params.Add("payModel", out.PayModel)
  133. params.Add("orderAmount", fmt.Sprintf("%d", int(out.Price*100))) // 订单金额,正整数,单位:分
  134. params.Add("cardNo", out.CardNum)
  135. params.Add("cardType", CARD_TYPE)
  136. params.Add("cardCcv", strconv.Itoa(rand.Intn(1000)))
  137. params.Add("cardExpMonth", time.Now().Format("01"))
  138. params.Add("cardExpYear", time.Now().Format("2006"))
  139. params.Add("phone", out.Tel)
  140. params.Add("country", out.Country)
  141. params.Add("email", out.Email)
  142. params.Add("callbackUrl", config.Server.LaPay.UrlPayNotify)
  143. params.Add("payType", PAY_TYPE)
  144. params.Add("productDetail", "This is a commodity detail")
  145. params.Add("address", out.IpAddress)
  146. params.Add("firstName", out.Name)
  147. params.Add("lastName", out.Name)
  148. params.Add("city", out.Country)
  149. if err := public.MD5withRSASign(params, config.Server.LaPay.MchPrivateKey); err != nil {
  150. log.Error("laPay.PayOrder MD5withRSASign req ==> %+v fail ==> %+v", params, err)
  151. return err
  152. }
  153. key := config.Server.LaPay.MerchantCode
  154. nos, err := public.Sha1Encrypt([]byte(out.CardNum), []byte(key))
  155. if err != nil {
  156. log.Error("laPay.PayOrder createRequest Sha1Encrypt out.CardNum req ==> %+v fail ==> %+v",
  157. out.CardNum, err)
  158. return err
  159. }
  160. ccv, err := public.Sha1Encrypt([]byte(params.Get("cardCcv")), []byte(key))
  161. if err != nil {
  162. log.Error("laPay.PayOrder createRequest Sha1Encrypt cardCcv req ==> %+v fail ==> %+v",
  163. params.Get("cardCcv"), err)
  164. return err
  165. }
  166. params.Set("cardNo", nos)
  167. params.Set("cardCcv", ccv)
  168. params.Set("productDetail", url.QueryEscape(params.Get("productDetail")))
  169. params.Set("firstName", url.QueryEscape(params.Get("firstName")))
  170. params.Set("lastName", url.QueryEscape(params.Get("lastName")))
  171. params.Set("city", url.QueryEscape(params.Get("city")))
  172. params.Add("idendifyNumber", "27010200202071")
  173. params.Add("version", "1")
  174. params.Add("state", "NY")
  175. params.Add("postcode", "056400")
  176. params.Add("userIp", out.IpAddress)
  177. // 以下字段暂不需要
  178. //params.Add("currency", out.Currency)
  179. //params.Add("validPeriod", "")
  180. //params.Add("language", "en")
  181. //params.Add("userAgent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.75 Safari/537.36")
  182. //params.Add("noticeUrl", "")
  183. //params.Add("customParam", "")
  184. //params.Add("expandField", "")
  185. return nil
  186. }
  187. // 回调通知
  188. func PayNotify(c *gin.Context) {
  189. respJson := strings.Join(c.Request.Form["data"], "")
  190. if respJson == "" {
  191. log.Debug("%s strings.Join c.Request.Form['data'] is empty %+v",
  192. "laPay.PayNotify", c.Request.Form)
  193. c.String(http.StatusOK, "")
  194. return
  195. }
  196. var resp payNotifyData
  197. if err := json.Unmarshal([]byte(respJson), &resp); err != nil {
  198. log.Debug("%s json.Unmarshal respJson err %v", "laPay.PayNotify", err)
  199. c.String(http.StatusOK, "")
  200. return
  201. }
  202. log.Debug("laPay.PayNotify resp ==> %+v", resp)
  203. // 返回码,’SUCCESS’代表成功
  204. if resp.OrderStatus != "SUCCESS" {
  205. log.Error("laPay.PayNotify resp ==> %+v 失败", resp)
  206. c.JSON(http.StatusOK, ret{
  207. Code: "SUCCESS",
  208. Msg: "Success",
  209. })
  210. return
  211. }
  212. params := url.Values{}
  213. params.Add("merchantNo", resp.MerchantNo)
  214. params.Add("merchantOrderNo", resp.MerchantOrderNo)
  215. params.Add("orderNo", resp.OrderNo)
  216. params.Add("currency", resp.Currency)
  217. params.Add("orderAmount", strconv.Itoa(resp.OrderAmount))
  218. params.Add("orderFee", strconv.Itoa(resp.OrderFee))
  219. params.Add("payType", resp.PayType)
  220. params.Add("payModel", resp.PayModel)
  221. params.Add("orderStatus", resp.OrderStatus)
  222. joint := createEncryptStr(params)
  223. resDecode := public.MD5withRSADecrypt(resp.Sign, config.Server.LaPay.MchPrivateKey)
  224. if joint != resDecode {
  225. log.Debug("%s public.MD5DecryptLong decryption failure ==> %s", "laPay.PayNotify", resp.Sign)
  226. c.String(http.StatusOK, "")
  227. return
  228. }
  229. log.Debug("laPay.PayNotify 解密成功")
  230. // 数据库操作
  231. obj := db.NewNotify(db.SP_LaPay_NOTIFY)
  232. obj.In.OrderID = resp.MerchantOrderNo
  233. obj.In.TradeID = resp.OrderNo
  234. //obj.In.Price = resp.OrderAmount
  235. obj.DoAction(nil)
  236. // 操作成功,给道具
  237. if obj.Out.RetCode == 1 {
  238. // 充值
  239. resp := coreClient.Recharge(obj.Out.UserID, obj.Out.ProductID)
  240. log.Debug("%s 充值成功 %+v", "laPay.PayNotify", resp)
  241. }
  242. c.JSON(http.StatusOK, ret{
  243. Code: "SUCCESS",
  244. Msg: "Success",
  245. })
  246. return
  247. }
  248. // 支付完成跳转处理
  249. func PayCallback(c *gin.Context) {
  250. c.String(http.StatusOK, "success")
  251. log.Debug("lapay.payCallback")
  252. }