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.

184 lignes
4.7KB

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