github.com/aarzilli/tools@v0.0.0-20151123112009-0d27094f75e0/net/http/blchain/blockchain.go (about) 1 // Implements https://blockchain.info/api/api_receive 2 package blchain 3 4 /* 5 6 Implementation cancelled, since responds to appspot request with 7 http error 429: too many requests. 8 9 We might add an API key from 10 https://blockchain.info/api/create_wallet 11 but we not gotten a response yet. 12 13 Instead we use https://github.com/piotrnar/gocoin 14 15 */ 16 17 import ( 18 "bytes" 19 "encoding/json" 20 "fmt" 21 "net/http" 22 "net/url" 23 24 "appengine" 25 26 "github.com/pbberlin/tools/net/http/fetch" 27 "github.com/pbberlin/tools/net/http/htmlfrag" 28 "github.com/pbberlin/tools/net/http/loghttp" 29 "github.com/pbberlin/tools/net/http/tplx" 30 "github.com/pbberlin/tools/stringspb" 31 ) 32 33 const uriRequestPayment = "/blockchain-integr/request" 34 const uriConfirmPayment = "/blockchain-integr/confirm" 35 36 const bitCoinAddress = "18tpXf8WWuhJP95JbDASbZvavmZJbrydut" 37 const blockChainHost = "blockchain.info" 38 const apiKey = "1b666d00-5110-45c0-bd6e-545452a116b4" 39 40 var wpf = fmt.Fprintf 41 42 // InitHandlers is called from outside, 43 // and makes the EndPoints available. 44 func InitHandlers() { 45 http.HandleFunc(uriRequestPayment, loghttp.Adapter(requestPay)) 46 http.HandleFunc(uriConfirmPayment, loghttp.Adapter(confirmPay)) 47 } 48 49 // BackendUIRendered returns a userinterface rendered to HTML 50 func BackendUIRendered() *bytes.Buffer { 51 var b1 = new(bytes.Buffer) 52 htmlfrag.Wb(b1, "BitCoin integration", uriRequestPayment, "request payment") 53 htmlfrag.Wb(b1, "Confirm", uriConfirmPayment, "") 54 55 return b1 56 } 57 58 func requestPay(w http.ResponseWriter, r *http.Request, m map[string]interface{}) { 59 60 lg, b := loghttp.BuffLoggerUniversal(w, r) 61 closureOverBuf := func(bUnused *bytes.Buffer) { 62 loghttp.Pf(w, r, b.String()) 63 } 64 defer closureOverBuf(b) // the argument is ignored, 65 r.Header.Set("X-Custom-Header-Counter", "nocounter") 66 67 protoc := "https://" 68 if appengine.IsDevAppServer() { 69 protoc = "http://" 70 } 71 72 host := appengine.DefaultVersionHostname(appengine.NewContext(r)) 73 if appengine.IsDevAppServer() { 74 host = "not-loclhost" 75 } 76 77 confirmURL := fmt.Sprintf("%v%v%v", protoc, host, uriConfirmPayment) 78 confirmURL = url.QueryEscape(confirmURL) 79 80 addrURL := fmt.Sprintf("https://%v/api/receive?method=create&address=%v&callback=%v&customsecret=49&api_code=%v", 81 blockChainHost, bitCoinAddress, confirmURL, apiKey) 82 83 req, err := http.NewRequest("GET", addrURL, nil) 84 lg(err) 85 if err != nil { 86 return 87 } 88 bts, inf, err := fetch.UrlGetter(r, fetch.Options{Req: req}) 89 bts = bytes.Replace(bts, []byte(`","`), []byte(`", "`), -1) 90 91 if err != nil { 92 lg(err) 93 lg(inf.Msg) 94 return 95 } 96 97 lg("response body 1:\n") 98 lg("%s\n", string(bts)) 99 100 lg("response body 2:\n") 101 var data1 map[string]interface{} 102 err = json.Unmarshal(bts, &data1) 103 lg(err) 104 lg(stringspb.IndentedDumpBytes(data1)) 105 // lg("%#v", data1) 106 107 inputAddress, ok := data1["input_address"].(string) 108 if !ok { 109 lg("input address could not be casted to string; is type %T", data1["input_address"]) 110 return 111 } 112 feePercent, ok := data1["fee_percent"].(float64) 113 if !ok { 114 lg("fee percent could not be casted to float64; is type %T", data1["fee_percent"]) 115 return 116 } 117 118 lg("Input Adress will be %q; fee percent will be %4.2v", inputAddress, feePercent) 119 120 } 121 122 /* 123 124 125 126 */ 127 func confirmPay(w http.ResponseWriter, r *http.Request, m map[string]interface{}) { 128 129 /* 130 131 132 http://abc.de/ef?input_transaction_hash=46178baf7de078954b5aebb71c12120b33d998faac1c165af195eae90f19b25c&shared=false&address=18tpXf8WWuhJP95JbDASbZvavmZJbrydut&destination_address=18tpXf8WWuhJP95JbDASbZvavmZJbrydut&input_address=1ZTnjSdknZvur9Gc73gvB8XBTWL7nV1m6&test=true&anonymous=false&confirmations=0&value=82493362&transaction_hash=46178baf7de078954b5aebb71c12120b33d998faac1c165af195eae90f19b25c 133 */ 134 135 lg, b := loghttp.BuffLoggerUniversal(w, r) 136 closureOverBuf := func(bUnused *bytes.Buffer) { 137 loghttp.Pf(w, r, b.String()) 138 } 139 defer closureOverBuf(b) // the argument is ignored, 140 r.Header.Set("X-Custom-Header-Counter", "nocounter") 141 142 wpf(b, tplx.ExecTplHelper(tplx.Head, map[string]interface{}{"HtmlTitle": "Payment confirmation"})) 143 defer wpf(b, tplx.Foot) 144 145 wpf(b, "<pre>") 146 defer wpf(b, "</pre>") 147 148 err := r.ParseForm() 149 lg(err) 150 151 custSecret := "" 152 if r.FormValue("customsecret") != "" { 153 custSecret = r.FormValue("customsecret") 154 } 155 lg("custom secret is %q", custSecret) 156 157 val := "" 158 if r.FormValue("value") != "" { 159 val = r.FormValue("value") 160 } 161 lg("value is %q", val) 162 163 }