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  }