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.

169 lines
4.3KB

  1. package main
  2. import (
  3. "io/ioutil"
  4. "log"
  5. "net/http"
  6. "net/url"
  7. "strconv"
  8. "strings"
  9. "time"
  10. )
  11. type LeanworkOut struct {
  12. Id int64
  13. Leanwork int64
  14. SignType string
  15. OrderNo string
  16. OrderAmount string
  17. OrderCurrency string
  18. TransactionId string
  19. Status string
  20. Sign string
  21. Ts time.Time
  22. LeanworkResp string
  23. }
  24. //inform Leanwork of final result, retry 5 times if not successful
  25. func (m *LeanworkOut) DoHttp() (retry bool, err error) {
  26. retry = true
  27. form := url.Values{}
  28. form.Set("signType", "MD5")
  29. form.Set("orderNo", m.OrderNo)
  30. form.Set("orderAmount", m.OrderAmount)
  31. form.Set("orderCurrency", m.OrderCurrency)
  32. form.Set("transactionId", m.TransactionId)
  33. form.Set("sign", m.Sign)
  34. lin, err := getLeanworkInById(m.Leanwork) //which is very unlikely
  35. if err != nil {
  36. log.Println("Fatal: Cannot get LeanworkIn by ID =" + strconv.FormatInt(m.Leanwork, 10) + "error " + err.Error())
  37. retry = false
  38. }
  39. resp, err := http.PostForm(lin.ReceiveUrl, form)
  40. if err != nil {
  41. log.Println("Leanwork Server Error, give bad response, " + err.Error())
  42. m.LeanworkResp = "Http Error: " + err.Error()
  43. m.add2db()
  44. return
  45. }
  46. defer resp.Body.Close()
  47. if resp.StatusCode == http.StatusOK {
  48. bodyBytes, err := ioutil.ReadAll(resp.Body)
  49. if err != nil {
  50. log.Println("Fatal: Cannot read leanwork Http Response " + err.Error())
  51. }
  52. bodyString := string(bodyBytes)
  53. m.LeanworkResp = bodyString
  54. m.add2db()
  55. if strings.Contains(strings.ToLower(bodyString), "success") {
  56. retry = false
  57. } else {
  58. log.Println("Leanwork response without success word : " + bodyString)
  59. }
  60. retry = false
  61. }
  62. return
  63. }
  64. func startLeanworkCallBack(ri RpnIn) {
  65. lo, err := buildLeanworkOutByRpnIn(ri)
  66. if err != nil {
  67. log.Printf("Fatal: cannot inform Leanwork %+v , \n\t%s\n", ri, err.Error())
  68. return
  69. }
  70. if ri.Pay_result != "3" {
  71. log.Printf("Warning: RpnIn is processing not informing leanwork %+v", ri)
  72. return
  73. }
  74. for i := 1; i <= 5; i++ {
  75. retry, err := lo.DoHttp()
  76. if !retry {
  77. break
  78. }
  79. time.Sleep(5 * time.Minute) //sleep 5 minute and try again
  80. log.Printf("Trying(%d) to report leanwork about transaction status %+v, encountered error %s \n", i, lo, err.Error())
  81. }
  82. }
  83. func buildLeanworkOutByRpnIn(ri RpnIn) (ret LeanworkOut, err error) {
  84. li, err := getLeanworkInById(ri.Leanwork)
  85. if err != nil {
  86. return
  87. }
  88. ret.Leanwork = ri.Leanwork
  89. ret.SignType = "MD5"
  90. ret.OrderNo = li.OrderNo
  91. ret.OrderAmount = li.OrderAmount
  92. ret.OrderCurrency = li.OrderCurrency
  93. ret.TransactionId = ri.Deal_id
  94. if ri.Pay_result == "3" {
  95. ret.Status = "success"
  96. } else if ri.Pay_result == "1" {
  97. ret.Status = "processing"
  98. }
  99. return
  100. }
  101. func (m *LeanworkOut) add2db() (ret LeanworkOut, err error) {
  102. if err = db.conn(Config); err != nil {
  103. return
  104. }
  105. defer db.close()
  106. q := `INSERT INTO leanworkOut(
  107. leanwork, signType, orderNo, orderAmount, orderCurrency,
  108. transactionId, status, sign, leanworkResp)
  109. VALUES(?,?,?,?,?,?,?,?,?)
  110. `
  111. insForm, err := db.h.Prepare(q)
  112. if err != nil {
  113. log.Printf("Failed to prepare SQL statment for insert leanworkOut" + err.Error())
  114. return
  115. }
  116. res, err := insForm.Exec(
  117. m.Leanwork, m.SignType, m.OrderNo, m.OrderAmount, m.OrderCurrency,
  118. m.TransactionId, m.Status, m.Sign, m.LeanworkResp)
  119. if err != nil {
  120. log.Printf("Error inserting leanworkOut with orderNo =%s, %s \n", m.OrderNo, err.Error())
  121. return
  122. }
  123. id, err := res.LastInsertId()
  124. if err != nil {
  125. log.Printf("Cannot retrieve lastInsertId for orderID %s", m.OrderNo)
  126. return
  127. }
  128. ret, err = getLeanWorkOutById(id)
  129. if err == nil {
  130. *m = ret
  131. }
  132. return
  133. }
  134. func getLeanWorkOutById(id int64) (row LeanworkOut, err error) {
  135. db.conn(Config)
  136. defer db.close()
  137. err = db.h.QueryRow("SELECT * FROM leanworkOut WHERE id=? ", id).Scan(
  138. &row.Id, &row.Leanwork, &row.SignType, &row.OrderNo, &row.OrderAmount,
  139. &row.OrderCurrency, &row.TransactionId, &row.Status, &row.Sign,
  140. &row.Ts, &row.LeanworkResp)
  141. return
  142. }
  143. func getLeanWorkOutByLeanworkId(id int64) (row LeanworkOut, err error) {
  144. db.conn(Config)
  145. defer db.close()
  146. err = db.h.QueryRow("SELECT * FROM leanworkOut WHERE leanwork=? ORDER BY id DESC LIMIT 1", id).Scan(
  147. &row.Id, &row.Leanwork, &row.SignType, &row.OrderNo, &row.OrderAmount,
  148. &row.OrderCurrency, &row.TransactionId, &row.Status, &row.Sign,
  149. &row.Ts, &row.LeanworkResp)
  150. return
  151. }