payment gateway for rpn cn
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

237 Zeilen
6.3KB

  1. package main
  2. import (
  3. "database/sql"
  4. "errors"
  5. "fmt"
  6. "log"
  7. "math"
  8. "net/http"
  9. "net/url"
  10. "strconv"
  11. "time"
  12. "github.com/go-sql-driver/mysql"
  13. )
  14. type RpnOut struct {
  15. Version string
  16. Sign_type string
  17. Mid string
  18. Notify_url string
  19. Order_amount string
  20. Order_time string //YYYYMMDDHHMMSS
  21. Order_id string
  22. User_id string
  23. User_name string
  24. User_cardno string
  25. Signature string
  26. //template
  27. Url string //where to post entire data structure
  28. //database specific
  29. Id int64
  30. Leanwork int64
  31. Ip4 uint32
  32. Ip4location sql.NullString
  33. Ts mysql.NullTime
  34. }
  35. // //build request from leanwork request forms
  36. // func (m *RpnOut) buildReqByForm(form url.Values) RpnOut {
  37. // r := RpnOut{}
  38. // r.version = "1.1"
  39. // r.sign_type = "MD5"
  40. // r.mid = "EU85201311P2P"
  41. // r.notify_url = "http://rpn.supertraderfx.ayvwd8em49pvoa3g.com/rpn_notify"
  42. // r.order_id = form["orderNo"][0]
  43. // r.order_amount = form["orderAmount"][0] //cents
  44. // r.order_time = m.now()
  45. // r.user_id = form["customerId"][0]
  46. // r.user_name = "SuperForex"
  47. // r.user_cardno = "6212262002002377849"
  48. // r.signature = md5RpnFormP2P(r)
  49. // *m = r
  50. // return r
  51. // }
  52. func (m *RpnOut) buildReqByLeanworkRequestP2P(row LeanworkRequest, user_name string, user_cardno string) RpnOut {
  53. m.Version = "1.1"
  54. m.Sign_type = "MD5"
  55. m.Mid = Config.Rpn.MIDP2P
  56. m.Notify_url = Config.Rpn.UrlCallBack
  57. m.Order_id = row.OrderNo
  58. m.Order_amount = m.translateAmountFromLeanwork(row.OrderAmount)
  59. m.Order_time = m.now()
  60. m.User_id = row.CustomerId
  61. m.User_name = user_name
  62. m.User_cardno = user_cardno
  63. m.Signature = md5RpnFormP2P(*m)
  64. m.Leanwork = row.Id
  65. return *m
  66. }
  67. func (m *RpnOut) buildReqByLeanworkRequestFAT(row LeanworkRequest, user_name string, user_cardno string) RpnOut {
  68. m.Version = "1.1"
  69. m.Sign_type = "MD5"
  70. m.Mid = Config.Rpn.MIDFAT
  71. m.Notify_url = Config.Rpn.UrlCallBack
  72. m.Order_id = row.OrderNo
  73. m.Order_amount = m.translateAmountFromLeanwork(row.OrderAmount)
  74. m.Order_time = m.now()
  75. m.User_id = row.CustomerId
  76. m.User_name = user_name
  77. m.User_cardno = user_cardno
  78. m.Signature = md5RpnFormFAT(*m)
  79. m.Leanwork = row.Id
  80. return *m
  81. }
  82. //from 0.1 to 10 cents
  83. func (m *RpnOut) translateAmountFromLeanwork(from string) string {
  84. f, _ := strconv.ParseFloat(from, 32)
  85. f = f * 100 //convert to cents
  86. t := int(math.Ceil(f))
  87. s := strconv.Itoa(t)
  88. return s
  89. }
  90. func (m *RpnOut) now() string {
  91. t := time.Now()
  92. return t.Format("20060102150405")
  93. }
  94. //send request to RPN to initiate transaction
  95. func (m *RpnOut) SendReq(form url.Values) (*http.Response, error) {
  96. return nil, nil
  97. // r := m.buildReqByForm(form)
  98. // hc := http.Client{Timeout: 15 * time.Second}
  99. // myForm := url.Values{}
  100. // myForm.Set("version", r.version)
  101. // myForm.Set("sign_type", r.sign_type)
  102. // myForm.Set("mid", r.mid)
  103. // myForm.Set("notify_url", r.notify_url)
  104. // myForm.Set("order_id", r.order_id)
  105. // myForm.Set("order_amount", r.order_amount)
  106. // myForm.Set("order_time", r.order_time)
  107. // myForm.Set("user_id", r.user_id)
  108. // myForm.Set("user_name", r.user_name)
  109. // myForm.Set("user_cardno", r.user_cardno)
  110. // myForm.Set("signature", r.signature)
  111. // //req, err := http.NewRequest("POST", "https://lawipac.com/dumprequest.php", strings.NewReader(myForm.Encode()))
  112. // req, err := http.NewRequest("POST", Config.Rpn.UrlTest, strings.NewReader(m.encode()))
  113. // if err != nil {
  114. // panic("wrong")
  115. // }
  116. // req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
  117. // req.Header.Add("content-Length", strconv.Itoa(len(form.Encode())))
  118. // return hc.Do(req)
  119. //Config.Rpn.UrlTest
  120. // return http.PostForm(Config.Rpn.UrlTest, myForm)
  121. //return http.PostForm("https://lawipac.com/dumprequest.php", myForm)
  122. }
  123. //encode without disturbing it's original order
  124. func (m *RpnOut) encode() string {
  125. s := "version=" + m.Version
  126. s += "&sign_type=" + m.Sign_type
  127. s += "&mid=" + m.Mid
  128. s += "&notify_url=" + url.QueryEscape(m.Notify_url)
  129. s += "&order_id=" + m.Order_id
  130. s += "&order_amount=" + m.Order_amount
  131. s += "&order_time=" + m.Order_time
  132. s += "&user_id=" + m.User_id
  133. s += "&user_name=" + url.QueryEscape(m.User_name)
  134. s += "&user_cardno=" + m.User_cardno
  135. s += "&signature=" + m.Signature
  136. return s
  137. }
  138. func retrieveFormValue(form url.Values, key string) (r string, err error) {
  139. if _, ok := form[key]; ok {
  140. r = form[key][0]
  141. err = nil
  142. } else {
  143. r = ""
  144. err = errors.New("Key [" + key + "] not found in HTTP request")
  145. }
  146. return r, err
  147. }
  148. func rpnNotify(w http.ResponseWriter, r *http.Request) {
  149. fmt.Fprint(w, "ok notify")
  150. }
  151. //receive RPN user name and card number
  152. func rpnNameAndCard(w http.ResponseWriter, r *http.Request) {
  153. if r.Method != "POST" {
  154. errPage(w, http.StatusMethodNotAllowed, "invalid request")
  155. return
  156. }
  157. r.ParseForm()
  158. id := r.FormValue("id")
  159. sign := r.FormValue("sign")
  160. user_name := r.FormValue("name")
  161. user_card := r.FormValue("card")
  162. rpn_type := r.FormValue("rpnType")
  163. if !(id != "" && sign != "" && user_name != "" && user_card != "") {
  164. errPage(w, http.StatusBadRequest, "missing parameters")
  165. return
  166. }
  167. row, err := getRequestRowByIdAndSign(id, sign)
  168. if err != nil {
  169. w.WriteHeader(http.StatusBadRequest)
  170. fmt.Fprintf(w, "bad parameters")
  171. return
  172. }
  173. ro := RpnOut{}
  174. ro.Ip4 = getClientIPLong(r)
  175. ro.Leanwork = row.Id
  176. if rpn_type == "rpnp2p" {
  177. ro.buildReqByLeanworkRequestP2P(row, user_name, user_card)
  178. } else {
  179. ro.buildReqByLeanworkRequestFAT(row, user_name, user_card)
  180. }
  181. //create db record
  182. db.addRpnOut(ro)
  183. //build rpn redirect page and send it
  184. ro.sendRedirect(w, row)
  185. }
  186. func (m *RpnOut) sendRedirect(w http.ResponseWriter, row LeanworkRequest) {
  187. //execute redirect
  188. m.Url = Config.Rpn.Url
  189. tmpl.ExecuteTemplate(w, "rpnCallOutRedirect", *m)
  190. }
  191. func getRpnOutByOrderId(order_id string) (ret RpnOut, err error) {
  192. if err = db.conn(Config); err != nil {
  193. return
  194. }
  195. defer db.close()
  196. q := "SELECT * FROM rpnOut WHERE order_id = ? ORDER BY id DESC LIMIT 1"
  197. err = db.h.QueryRow(q, order_id).Scan(
  198. &ret.Id, &ret.Leanwork, &ret.Version,
  199. &ret.Sign_type, &ret.Mid, &ret.Notify_url,
  200. &ret.Order_amount, &ret.Order_time, &ret.Order_id,
  201. &ret.User_id, &ret.User_name, &ret.User_cardno, &ret.Signature,
  202. &ret.Ip4, &ret.Ip4location, &ret.Ts)
  203. if err != nil {
  204. if err == sql.ErrNoRows {
  205. log.Println("trying to retrieve rpnOut(order_id=" + order_id + ") but not found")
  206. } else {
  207. log.Println("Error retrieving rpnOut(order_id=" + order_id + ") encountered : " + err.Error())
  208. }
  209. }
  210. return
  211. }