payment gateway for rpn cn
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

140 lines
3.5KB

  1. package main
  2. import (
  3. "database/sql"
  4. "log"
  5. "math"
  6. "net/http"
  7. "net/url"
  8. "strconv"
  9. "time"
  10. "github.com/go-sql-driver/mysql"
  11. )
  12. type RpnOut struct {
  13. Version string
  14. Sign_type string
  15. Mid string
  16. Notify_url string
  17. Order_amount string
  18. Order_time string //YYYYMMDDHHMMSS
  19. Order_id string
  20. User_id string
  21. User_name string
  22. User_cardno string
  23. Signature string
  24. //template
  25. Url string //where to post entire data structure
  26. //database specific
  27. Id int64
  28. Leanwork int64
  29. Ip4 uint32
  30. Ip4location sql.NullString
  31. Ts mysql.NullTime
  32. }
  33. func (m *RpnOut) buildReqByLeanworkINP2P(row LeanworkIn, user_name string, user_cardno string) RpnOut {
  34. m.Version = "1.1"
  35. m.Sign_type = "MD5"
  36. m.Mid = Config.Rpn.MIDP2P
  37. m.Notify_url = Config.Rpn.UrlCallBack
  38. m.Order_id = row.OrderNo
  39. m.Order_amount = m.translateAmountFromLeanwork(row.OrderAmount)
  40. m.Order_time = m.now()
  41. m.User_id = row.CustomerId
  42. m.User_name = user_name
  43. m.User_cardno = user_cardno
  44. m.Signature = md5RpnFormP2P(*m)
  45. m.Leanwork = row.Id
  46. return *m
  47. }
  48. func (m *RpnOut) buildReqByLeanworkINFAT(row LeanworkIn, user_name string, user_cardno string) RpnOut {
  49. m.Version = "1.1"
  50. m.Sign_type = "MD5"
  51. m.Mid = Config.Rpn.MIDFAT
  52. m.Notify_url = Config.Rpn.UrlCallBack
  53. m.Order_id = row.OrderNo
  54. m.Order_amount = m.translateAmountFromLeanwork(row.OrderAmount)
  55. m.Order_time = m.now()
  56. m.User_id = row.CustomerId
  57. m.User_name = user_name
  58. m.User_cardno = user_cardno
  59. m.Signature = md5RpnFormFAT(*m)
  60. m.Leanwork = row.Id
  61. return *m
  62. }
  63. //from 0.1 to 10 cents
  64. func (m *RpnOut) translateAmountFromLeanwork(from string) string {
  65. f, _ := strconv.ParseFloat(from, 32)
  66. f = f * 100 //convert to cents
  67. t := int(math.Ceil(f))
  68. s := strconv.Itoa(t)
  69. return s
  70. }
  71. func (m *RpnOut) now() string {
  72. t := time.Now()
  73. return t.Format("20060102150405")
  74. }
  75. //encode without disturbing it's original order
  76. func (m *RpnOut) encode() string {
  77. s := "version=" + m.Version
  78. s += "&sign_type=" + m.Sign_type
  79. s += "&mid=" + m.Mid
  80. s += "&notify_url=" + url.QueryEscape(m.Notify_url)
  81. s += "&order_id=" + m.Order_id
  82. s += "&order_amount=" + m.Order_amount
  83. s += "&order_time=" + m.Order_time
  84. s += "&user_id=" + m.User_id
  85. s += "&user_name=" + url.QueryEscape(m.User_name)
  86. s += "&user_cardno=" + m.User_cardno
  87. s += "&signature=" + m.Signature
  88. return s
  89. }
  90. func (m *RpnOut) sendRedirect(w http.ResponseWriter, row LeanworkIn) {
  91. //execute redirect
  92. m.Url = Config.Rpn.Url
  93. tmpl.ExecuteTemplate(w, "rpnCallOutRedirect", *m)
  94. }
  95. func (m *RpnOut) getMD5Key() string {
  96. if m.Mid == Config.Rpn.MIDP2P {
  97. return Config.Rpn.MD5P2P
  98. } else if m.Mid == Config.Rpn.MIDFAT {
  99. return Config.Rpn.MD5FAT
  100. } else {
  101. log.Println("WARNING: rpnOut::getMD5Key() has bad Mid = " + m.Mid + " cannot determin P2P or FAT, MID not match config")
  102. return ""
  103. }
  104. }
  105. func getRpnOutByOrderId(order_id string) (ret RpnOut, err error) {
  106. if err = db.conn(Config); err != nil {
  107. return
  108. }
  109. defer db.close()
  110. q := "SELECT * FROM rpnOut WHERE order_id = ? ORDER BY id DESC LIMIT 1"
  111. err = db.h.QueryRow(q, order_id).Scan(
  112. &ret.Id, &ret.Leanwork, &ret.Version,
  113. &ret.Sign_type, &ret.Mid, &ret.Notify_url,
  114. &ret.Order_amount, &ret.Order_time, &ret.Order_id,
  115. &ret.User_id, &ret.User_name, &ret.User_cardno, &ret.Signature,
  116. &ret.Ip4, &ret.Ip4location, &ret.Ts)
  117. if err != nil {
  118. if err == sql.ErrNoRows {
  119. log.Println("trying to retrieve rpnOut(order_id=" + order_id + ") but not found")
  120. } else {
  121. log.Println("Error retrieving rpnOut(order_id=" + order_id + ") encountered : " + err.Error())
  122. }
  123. }
  124. return
  125. }