| @@ -1 +1 @@ | |||
| {"files":{"dashboard.html":{"frameworks":["form","pg.insight.events","pg.css.grid","pg.image.overlay","pg.code-validator","pg.project.items","pg.asset.manager","bs4","pg.html","pg.components"],"last_page_width":1024},"index.html":{"frameworks":["PG","pg.insight.events","pg.asset.manager","pg.project.items","pg.css.grid","pg.code-validator","pg.image.overlay","bs4","pg.html","pg.components"],"last_page_width":1024},"rpnAskNameAndCard.html":{"frameworks":["PG","pg.insight.events","pg.asset.manager","pg.css.grid","pg.project.items","pg.image.overlay","pg.code-validator","bs4","pg.html","pg.components"],"last_page_width":1024},"error.html":{"frameworks":["PG","pg.insight.events","pg.css.grid","pg.image.overlay","pg.code-validator","pg.project.items","pg.asset.manager","bs4","pg.html","pg.components"],"last_page_width":1024},"StartPay.html":{"frameworks":["PG","pg.insight.events","pg.asset.manager","pg.project.items","pg.code-validator","pg.css.grid","pg.image.overlay","bs4","pg.html","pg.components"],"last_page_width":1024}},"breakpoints":["576px","768px","992px","1200px"],"frameworks":["PG","pg.insight.events","pg.css.grid","pg.image.overlay","pg.code-validator","pg.project.items","pg.asset.manager","bs4","pg.html","pg.components"],"template_framework_id":"bootstrap"} | |||
| {"files":{"dashboard.html":{"frameworks":["form","pg.insight.events","pg.css.grid","pg.image.overlay","pg.code-validator","pg.project.items","pg.asset.manager","bs4","pg.html","pg.components"],"last_page_width":1024},"index.html":{"frameworks":["PG","pg.insight.events","pg.asset.manager","pg.project.items","pg.css.grid","pg.code-validator","pg.image.overlay","bs4","pg.html","pg.components"],"last_page_width":1024},"rpnAskNameAndCard.html":{"frameworks":["PG","pg.insight.events","pg.asset.manager","pg.css.grid","pg.project.items","pg.image.overlay","pg.code-validator","bs4","pg.html","pg.components"],"last_page_width":1024},"error.html":{"frameworks":["PG","pg.insight.events","pg.css.grid","pg.image.overlay","pg.code-validator","pg.project.items","pg.asset.manager","bs4","pg.html","pg.components"],"last_page_width":1024},"StartPay.html":{"frameworks":["PG","pg.insight.events","pg.asset.manager","pg.project.items","pg.code-validator","pg.css.grid","pg.image.overlay","bs4","pg.html","pg.components"],"last_page_width":1024}},"breakpoints":["576px","768px","992px","1200px"],"frameworks":["PG","pg.insight.events","pg.asset.manager","pg.css.grid","pg.project.items","pg.image.overlay","pg.code-validator","bs4","pg.html","pg.components"],"template_framework_id":"bootstrap"} | |||
| @@ -21,18 +21,18 @@ | |||
| <p class="card-text">转帐之前,请预留您的卡号和姓名,转帐单将会核对没一笔交易,卡号</p> | |||
| <div class="alert alert-primary" role="alert">出账的卡号和姓名必须和网银转帐的信息一致,否则将会极大的延迟转帐时间和过程</div> | |||
| <form method="POST" action="/rpnNameAndCard"> | |||
| <input type="hidden" name="id" value="{{.Id}}"/> | |||
| <input type="hidden" name="sign" value="{{.Sign}}"/> | |||
| <input type="hidden" name="rpnType" value="{{.RpnType}}"/> | |||
| <input type="hidden" name="id" value="{{.Id}}"> | |||
| <input type="hidden" name="sign" value="{{.Sign}}"> | |||
| <input type="hidden" name="rpnType" value="{{.RpnType}}"> | |||
| <div class="form-group"> | |||
| <label for="formGroupExampleInput">您即将使用的银行卡号</label> | |||
| <label for="formGroupExampleInput">转出账户卡号</label> | |||
| <input type="text" class="form-control" id="formGroupExampleInput" name="card" placeholder="6212262002002377849"> | |||
| </div> | |||
| <div class="form-group"> | |||
| <label for="formGroupExampleInput2">上述银行卡,持卡人姓名</label> | |||
| <div class="form-group">转出账户姓名 | |||
| <br> | |||
| <input type="text" class="form-control" id="formGroupExampleInput2" name="name" placeholder="王建林"> | |||
| </div> | |||
| <input type="submit" class="btn btn-primary btn-lg btn-block" style="margin-top: 50px;" value="下一步"/> | |||
| <input type="submit" class="btn btn-primary btn-lg btn-block" style="margin-top: 50px;" value="下一步"> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| @@ -9,12 +9,13 @@ import ( | |||
| type AppConfig struct { | |||
| Rpn struct { | |||
| Url string `json:Url` | |||
| UrlTest string `json:UrlTest` | |||
| MD5P2P string `json:MD5P2P` | |||
| MD5FAT string `json:MD5FAT` | |||
| MIDP2P string `json:MIDP2P` | |||
| MIDFAT string `json:MIDFAT` | |||
| Url string `json:Url` | |||
| UrlTest string `json:UrlTest` | |||
| MD5P2P string `json:MD5P2P` | |||
| MD5FAT string `json:MD5FAT` | |||
| MIDP2P string `json:MIDP2P` | |||
| MIDFAT string `json:MIDFAT` | |||
| UrlCallBack string `json:UrlCallBack` | |||
| } `json:Rpn` | |||
| LeanWork struct { | |||
| MD5Key string `json:MD5Key` | |||
| @@ -4,7 +4,8 @@ | |||
| "MIDP2P": "EU85201311P2P", | |||
| "MD5P2P": "p1j4A3mEMj+ft0xkSfVULQ", | |||
| "MIDFAT": "EU85201311FAT", | |||
| "MD5FAT": "24QSfwYtH+tbefkMFPhuew" | |||
| "MD5FAT": "24QSfwYtH+tbefkMFPhuew", | |||
| "UrlCallBack": "http://rpn.supertraderfx.ayvwd8em49pvoa3g.com/rpn_notify" | |||
| }, | |||
| "LeanWork": { | |||
| "MD5Key": "492815086935204", | |||
| @@ -4,7 +4,8 @@ | |||
| "MIDP2P": "EU85201311P2P", | |||
| "MD5P2P": "p1j4A3mEMj+ft0xkSfVULQ", | |||
| "MIDFAT": "EU85201311FAT", | |||
| "MD5FAT": "24QSfwYtH+tbefkMFPhuew" | |||
| "MD5FAT": "24QSfwYtH+tbefkMFPhuew", | |||
| "UrlCallBack": "http://debug.biukop.com:8080/rpn_notify" | |||
| }, | |||
| "LeanWork": { | |||
| "MD5Key": "492815086935204", | |||
| @@ -14,12 +14,16 @@ type TransactionDB struct { | |||
| var db TransactionDB | |||
| func (m *TransactionDB) conn(c AppConfig) error { | |||
| if m.h != nil { | |||
| return nil //already connected, prevent multiple connection | |||
| } | |||
| dbDriver := c.DB.Driver | |||
| dbUser := c.DB.User | |||
| dbPass := c.DB.Pass | |||
| dbName := c.DB.Schema | |||
| h, err := sql.Open(dbDriver, dbUser+":"+dbPass+"@/"+dbName) | |||
| if err != nil { | |||
| m.h = nil | |||
| panic(err.Error()) | |||
| } | |||
| m.h = h | |||
| @@ -27,7 +31,10 @@ func (m *TransactionDB) conn(c AppConfig) error { | |||
| } | |||
| func (m *TransactionDB) close() { | |||
| defer m.h.Close() | |||
| if m.h != nil { | |||
| m.h.Close() | |||
| } | |||
| m.h = nil //clear it, very important to prevent multiple opening | |||
| } | |||
| func (m *TransactionDB) addRequest(r *http.Request) (row LeanworkRequest, err error) { | |||
| @@ -83,8 +90,51 @@ func (m *TransactionDB) addRequest(r *http.Request) (row LeanworkRequest, err er | |||
| return row, err | |||
| } | |||
| func (m *TransactionDB) addRpnOut(r RpnReq) error { | |||
| return nil | |||
| func (m *TransactionDB) addRpnOut(r RpnReq) (row RpnReq, err error) { | |||
| if err = m.conn(Config); err != nil { | |||
| return row, err | |||
| } | |||
| defer m.close() | |||
| sql := `INSERT INTO rpnOut | |||
| (order_id, version, sign_type, mid, notify_url, order_amount, order_time, | |||
| user_id, user_name, user_cardno, signature, leanwork, ip4 ) | |||
| VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)` | |||
| insForm, err := m.h.Prepare(sql) | |||
| if err != nil { | |||
| log.Println("cannot insert RpnOut record, sql prepare failed " + err.Error()) | |||
| return | |||
| } | |||
| order_id := r.Order_id | |||
| version := r.Version | |||
| sign_type := r.Sign_type | |||
| mid := r.Mid | |||
| notify_url := r.Notify_url | |||
| order_amount := r.Order_amount | |||
| order_time := r.Order_time | |||
| user_id := r.User_id | |||
| user_name := r.User_name | |||
| user_cardno := r.User_cardno | |||
| signature := r.Signature | |||
| leanwork := r.Leanwork | |||
| ip4 := r.Ip4 | |||
| res, err := insForm.Exec(order_id, version, sign_type, mid, notify_url, order_amount, order_time, | |||
| user_id, user_name, user_cardno, signature, leanwork, ip4) | |||
| if err != nil { | |||
| log.Println("Failed to execute sql statment for insert RpnOut order_id=" + r.Order_id + " " + err.Error()) | |||
| return | |||
| } | |||
| id, err := res.LastInsertId() | |||
| if err != nil { | |||
| log.Println("Cannot get last insert ID with new RpnOut record") | |||
| return | |||
| } | |||
| row = r | |||
| row.Id = id | |||
| return row, err | |||
| } | |||
| func (m *TransactionDB) updateRpnOutNameAndCard(orderid string, signature string, name string, card string) (row RpnReq, err error) { | |||
| @@ -9,6 +9,7 @@ import ( | |||
| func main() { | |||
| //readConfig() | |||
| readConfigForTest() | |||
| db.h = nil //make sure it's in proper state. | |||
| http.HandleFunc("/choosePayment", choosePayment) | |||
| http.HandleFunc("/rpnNameAndCard", rpnNameAndCard) | |||
| @@ -8,25 +8,31 @@ import ( | |||
| "net/url" | |||
| "strconv" | |||
| "time" | |||
| "github.com/go-sql-driver/mysql" | |||
| ) | |||
| // var url = "https://deposit.paylomo.net/pay.php?r=payEasy" //production | |||
| // var url = "https://deposit-mac.chinapaytech.com/pay.php?r=payEasy" //test | |||
| // var md5p2p = "370296119874502" | |||
| // var md5fat = "207841502473198" | |||
| type RpnReq struct { | |||
| Order_id string | |||
| Version string | |||
| Sign_type string | |||
| Mid string | |||
| Notify_url string | |||
| Order_id string | |||
| Order_amount string | |||
| Order_time string //YYYYMMDDHHMMSS | |||
| User_id string | |||
| User_name string | |||
| User_cardno string | |||
| Signature string | |||
| Url string //where to post entire data structure | |||
| //template | |||
| Url string //where to post entire data structure | |||
| //database specific | |||
| Id int64 | |||
| Leanwork int64 | |||
| Callback int64 | |||
| Ip4 uint32 | |||
| Ip4location string | |||
| Ts mysql.NullTime | |||
| } | |||
| // //build request from leanwork request forms | |||
| @@ -48,37 +54,37 @@ type RpnReq struct { | |||
| // } | |||
| func (m *RpnReq) buildReqByLeanworkRequestP2P(row LeanworkRequest, user_name string, user_cardno string) RpnReq { | |||
| r := RpnReq{} | |||
| r.Version = "1.1" | |||
| r.Sign_type = "MD5" | |||
| r.Mid = Config.Rpn.MIDP2P | |||
| r.Notify_url = "http://rpn.supertraderfx.ayvwd8em49pvoa3g.com/rpn_notify" | |||
| r.Order_id = row.OrderNo | |||
| r.Order_amount = m.translateAmountFromLeanwork(row.OrderAmount) | |||
| r.Order_time = m.now() | |||
| r.User_id = row.CustomerId | |||
| r.User_name = user_name | |||
| r.User_cardno = user_cardno | |||
| r.Signature = md5RpnFormP2P(r) | |||
| *m = r | |||
| return r | |||
| m.Version = "1.1" | |||
| m.Sign_type = "MD5" | |||
| m.Mid = Config.Rpn.MIDP2P | |||
| m.Notify_url = Config.Rpn.UrlCallBack | |||
| m.Order_id = row.OrderNo | |||
| m.Order_amount = m.translateAmountFromLeanwork(row.OrderAmount) | |||
| m.Order_time = m.now() | |||
| m.User_id = row.CustomerId | |||
| m.User_name = user_name | |||
| m.User_cardno = user_cardno | |||
| m.Signature = md5RpnFormP2P(*m) | |||
| m.Leanwork = row.Id | |||
| return *m | |||
| } | |||
| func (m *RpnReq) buildReqByLeanworkRequestFAT(row LeanworkRequest, user_name string, user_cardno string) RpnReq { | |||
| r := RpnReq{} | |||
| r.Version = "1.1" | |||
| r.Sign_type = "MD5" | |||
| r.Mid = Config.Rpn.MIDFAT | |||
| r.Notify_url = "http://rpn.supertraderfx.ayvwd8em49pvoa3g.com/rpn_notify" | |||
| r.Order_id = row.OrderNo | |||
| r.Order_amount = m.translateAmountFromLeanwork(row.OrderAmount) | |||
| r.Order_time = m.now() | |||
| r.User_id = row.CustomerId | |||
| r.User_name = user_name | |||
| r.User_cardno = user_cardno | |||
| r.Signature = md5RpnFormFAT(r) | |||
| *m = r | |||
| return r | |||
| m.Version = "1.1" | |||
| m.Sign_type = "MD5" | |||
| m.Mid = Config.Rpn.MIDFAT | |||
| m.Notify_url = Config.Rpn.UrlCallBack | |||
| m.Order_id = row.OrderNo | |||
| m.Order_amount = m.translateAmountFromLeanwork(row.OrderAmount) | |||
| m.Order_time = m.now() | |||
| m.User_id = row.CustomerId | |||
| m.User_name = user_name | |||
| m.User_cardno = user_cardno | |||
| m.Signature = md5RpnFormFAT(*m) | |||
| m.Leanwork = row.Id | |||
| return *m | |||
| } | |||
| //from 0.1 to 10 cents | |||
| @@ -156,7 +162,7 @@ func retrieveFormValue(form url.Values, key string) (r string, err error) { | |||
| return r, err | |||
| } | |||
| func rpnNotify(w http.ResponseWriter, r *http.Request) { | |||
| fmt.Fprint(w, "ok notify") | |||
| } | |||
| //receive RPN user name and card number | |||
| @@ -185,17 +191,22 @@ func rpnNameAndCard(w http.ResponseWriter, r *http.Request) { | |||
| } | |||
| ro := RpnReq{} | |||
| ro.Ip4 = getClientIPLong(r) | |||
| ro.Leanwork = row.Id | |||
| if rpn_type == "rpnp2p" { | |||
| ro.buildReqByLeanworkRequestP2P(row, user_name, user_card) | |||
| } else { | |||
| ro.buildReqByLeanworkRequestFAT(row, user_name, user_card) | |||
| } | |||
| //create db record | |||
| db.addRpnOut(ro) | |||
| //build rpn redirect page and send it | |||
| ro.sendRedirect(w, row) | |||
| } | |||
| func (m *RpnReq) sendRedirect(w http.ResponseWriter, row LeanworkRequest) { | |||
| //create db record | |||
| //execute redirect | |||
| m.Url = Config.Rpn.Url | |||
| tmpl.ExecuteTemplate(w, "rpnCallOutRedirect", *m) | |||
| } | |||