payment gateway for rpn cn
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

237 lignes
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. }