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.

188 satır
5.1KB

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