From 0225e69de2575bfe289f6eae86287af33fbf07d1 Mon Sep 17 00:00:00 2001 From: Alessandro Date: Thu, 7 May 2020 00:05:06 +0200 Subject: [PATCH 01/14] Added Request Headers in GetInvoice. Added Auth in GetInvoice. --- client/client.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/client/client.go b/client/client.go index 08fdd84..6788795 100644 --- a/client/client.go +++ b/client/client.go @@ -144,7 +144,14 @@ func (client *Client) Post(path string, paylo map[string]string) (response *http func (client *Client) GetInvoice(invId string) (inv invoice, err error) { url := client.ApiUri + "/invoices/" + invId htclient := setHttpClient(client) - response, _ := htclient.Get(url) + req, _ := http.NewRequest("GET", url, nil) + req.Header.Add("content-type", "application/json") + req.Header.Add("X-accept-version", "2.0.0") + publ := ku.ExtractCompressedPublicKey(client.Pem) + req.Header.Add("X-Identity", publ) + sig := ku.Sign(url, client.Pem) + req.Header.Add("X-Signature", sig) + response, _ := htclient.Do(req) inv, err = processInvoice(response) return inv, err } From 3b57eb3ffac5722a9fa4963d14f306adf416a8f2 Mon Sep 17 00:00:00 2001 From: Alessandro Date: Sat, 9 May 2020 22:40:26 +0200 Subject: [PATCH 02/14] Added CreatePayout --- client/client.go | 68 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/client/client.go b/client/client.go index 6788795..58bf121 100644 --- a/client/client.go +++ b/client/client.go @@ -11,6 +11,7 @@ import ( "net/http" "regexp" "strconv" + "time" ) // The Client struct maintains the state of the current client. To use a client from session to session, the Pem and Token will need to be saved and used in the next client. The ClientId can be recreated by using the key_util.GenerateSinFromPem func, and the ApiUri will generally be https://bitpay.com. Insecure should generally be set to false or not set at all, there are a limited number of test scenarios in which it must be set to true. @@ -54,6 +55,57 @@ type invoice struct { Token string } +type Payout struct { + Id string + Account string + Reference string + SupportPhone string + Status string + Amount float64 + PercentFee float64 + Fee float64 + DepositTotal float64 + Btc float64 + Currency string + RequestDate time.Time + EffectiveDate time.Time + NotificationUrl string + NotificationEmail string + Instructions []Instruction + Token string +} + +type Btc struct { + Unpaid int + Paid int +} + +type Instruction struct { + Id string + Amount float64 + Btc Btc + Address string + Label string + Status string + WalletProvider string + Receiverinfo Receiverinfo +} + +type Receiverinfo struct { + Name string + EmailAddress string + Address Address +} + +type Address struct { + StreetAddress1 string + StreetAddress2 string + Locality string + Region string + PostalCode string + Country string +} + // CreateInvoice returns an invoice type or pass the error from the server. The method will create an invoice on the BitPay server. func (client *Client) CreateInvoice(price float64, currency string) (inv invoice, err error) { match, _ := regexp.MatchString("^[[:upper:]]{3}$", currency) @@ -124,7 +176,7 @@ func (client *Client) PairClient(paylo map[string]string) (tok Token, err error) return tok, err } -func (client *Client) Post(path string, paylo map[string]string) (response *http.Response, err error) { +func (client *Client) Post(path string, paylo interface{}) (response *http.Response, err error) { url := client.ApiUri + "/" + path htclient := setHttpClient(client) payload, _ := json.Marshal(paylo) @@ -234,3 +286,17 @@ func processInvoice(response *http.Response) (inv invoice, err error) { } return inv, err } + +// CreatePayout create and returns a PayOut. +func (client *Client) CreatePayout(p Payout) (payout Payout, err error) { + match, _ := regexp.MatchString("^[[:upper:]]{3}$", p.Currency) + if !match { + err = errors.New("BitPayArgumentError: invalid currency code") + return payout, err + } + p.Token = client.Token.Token + response, err := client.Post("payouts", p) + body, err := ioutil.ReadAll(response.Body) + json.Unmarshal(body, &payout) + return payout, err +} From b9ec34a995bea5996a572718ed327ad31d34f97b Mon Sep 17 00:00:00 2001 From: AlessandroSechi Date: Sat, 16 May 2020 02:29:01 +0200 Subject: [PATCH 03/14] Edited Create Invoice --- client/client.go | 59 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/client/client.go b/client/client.go index 58bf121..ec64968 100644 --- a/client/client.go +++ b/client/client.go @@ -33,6 +33,39 @@ type Token struct { PairingCode string } +type Invoice struct { + Token string + Price float64 + Currency string + OrderId string + ItemDesc string + ItemCode string + NotificationEmail string + NotificationUrl string + RedirectUrl string + PosData string + TransactionSpeed string + FullNotifications string + ExtendedNotifications string + Physical string + Buyer Buyer + PaymentCurrencies []string + JsonPayProRequired string +} + +type Buyer struct { + Name string + Address1 string + Address2 string + Locality string + Region string + PostalCode string + Country string + Email string + Phone string + Notify bool +} + // Go struct mapping the JSON returned from the BitPay server when sending a POST or GET request to /invoices. type invoice struct { @@ -107,27 +140,19 @@ type Address struct { } // CreateInvoice returns an invoice type or pass the error from the server. The method will create an invoice on the BitPay server. -func (client *Client) CreateInvoice(price float64, currency string) (inv invoice, err error) { - match, _ := regexp.MatchString("^[[:upper:]]{3}$", currency) +func (client *Client) CreateInvoice(i Invoice) (inv invoice, err error) { + match, _ := regexp.MatchString("^[[:upper:]]{3}$", i.Currency) if !match { err = errors.New("BitPayArgumentError: invalid currency code") return inv, err } - paylo := make(map[string]string) - var floatPrec int - if currency == "BTC" { - floatPrec = 8 - } else { - floatPrec = 2 - } - priceString := strconv.FormatFloat(price, 'f', floatPrec, 64) - paylo["price"] = priceString - paylo["currency"] = currency - paylo["token"] = client.Token.Token - paylo["id"] = client.ClientId - response, _ := client.Post("invoices", paylo) - inv, err = processInvoice(response) - return inv, err + + i.Token = client.Token.Token + response, _ := client.Post("invoices", i) + body, err := ioutil.ReadAll(response.Body) + var invoice invoice + json.Unmarshal(body, &invoice) + return invoice, err } // PairWithFacade From ac9e7d1e5f15f587270efe82e0884fc7b594e02f Mon Sep 17 00:00:00 2001 From: AlessandroSechi Date: Sat, 16 May 2020 11:55:37 +0200 Subject: [PATCH 04/14] Create Invoice JSONEmpty --- client/client.go | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/client/client.go b/client/client.go index ec64968..079f7a0 100644 --- a/client/client.go +++ b/client/client.go @@ -37,33 +37,33 @@ type Invoice struct { Token string Price float64 Currency string - OrderId string - ItemDesc string - ItemCode string - NotificationEmail string - NotificationUrl string - RedirectUrl string - PosData string - TransactionSpeed string - FullNotifications string - ExtendedNotifications string - Physical string - Buyer Buyer - PaymentCurrencies []string - JsonPayProRequired string + OrderId string `json:",omitempty"` + ItemDesc string `json:",omitempty"` + ItemCode string `json:",omitempty"` + NotificationEmail string `json:",omitempty"` + NotificationUrl string `json:",omitempty"` + RedirectUrl string `json:",omitempty"` + PosData string `json:",omitempty"` + TransactionSpeed string `json:",omitempty"` + FullNotifications string `json:",omitempty"` + ExtendedNotifications string `json:",omitempty"` + Physical string `json:",omitempty"` + Buyer Buyer `json:",omitempty"` + PaymentCurrencies []string `json:",omitempty"` + JsonPayProRequired string `json:",omitempty"` } type Buyer struct { - Name string - Address1 string - Address2 string - Locality string - Region string - PostalCode string - Country string - Email string - Phone string - Notify bool + Name string `json:",omitempty"` + Address1 string `json:",omitempty"` + Address2 string `json:",omitempty"` + Locality string `json:",omitempty"` + Region string `json:",omitempty"` + PostalCode string `json:",omitempty"` + Country string `json:",omitempty"` + Email string `json:",omitempty"` + Phone string `json:",omitempty"` + Notify bool `json:",omitempty"` } // Go struct mapping the JSON returned from the BitPay server when sending a POST or GET request to /invoices. From 9a4f096949e7a6d442a6a5fe6dec0a7bff27e3fb Mon Sep 17 00:00:00 2001 From: AlessandroSechi Date: Sat, 16 May 2020 12:25:50 +0200 Subject: [PATCH 05/14] Create Invoice New Fields --- client/client.go | 88 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 5 deletions(-) diff --git a/client/client.go b/client/client.go index 079f7a0..464520a 100644 --- a/client/client.go +++ b/client/client.go @@ -34,9 +34,9 @@ type Token struct { } type Invoice struct { - Token string - Price float64 - Currency string + Token string `json:",omitempty"` + Price float64 `json:",omitempty"` + Currency string `json:",omitempty"` OrderId string `json:",omitempty"` ItemDesc string `json:",omitempty"` ItemCode string `json:",omitempty"` @@ -51,6 +51,26 @@ type Invoice struct { Buyer Buyer `json:",omitempty"` PaymentCurrencies []string `json:",omitempty"` JsonPayProRequired string `json:",omitempty"` + //Additional Response Fiend + Url string `json:",omitempty"` + Status string `json:",omitempty"` + InvoiceTime time.Time `json:",omitempty"` + ExpirationTime time.Time `json:",omitempty"` + CurrentTime time.Time `json:",omitempty"` + Id string `json:",omitempty"` + LowFeeDetected bool `json:",omitempty"` + AmountPaid float64 `json:",omitempty"` + DisplayAmountPaid float64 `json:",omitempty"` + ExceptionStatus bool `json:",omitempty"` + RefundAddressRequestPending bool `json:",omitempty"` + BuyerProvidedInfo Buyer `json:",omitempty"` + PaymentSubtotals PaymentTotals `json:",omitempty"` + PaymentTotals PaymentTotals `json:",omitempty"` + PaymentDisplayTotals PaymentDisplay `json:",omitempty"` + PaymentDisplaySubTotals PaymentDisplay `json:",omitempty"` + ExchangeRates ExchangeRates `json:",omitempty"` + SupportedTransactionCurrencies SupportedTransactionCurrencies `json:",omitempty"` + MinerFees MinerFees `json:",omitempty"` } type Buyer struct { @@ -66,6 +86,64 @@ type Buyer struct { Notify bool `json:",omitempty"` } +type PaymentTotals struct { + Btc float64 `json:",omitempty"` + Bch float64 `json:",omitempty"` + Eth float64 `json:",omitempty"` + Gusd float64 `json:",omitempty"` + Pax float64 `json:",omitempty"` + Busd float64 `json:",omitempty"` + Usdc float64 `json:",omitempty"` + Xrp float64 `json:",omitempty"` + Enabled bool `json:",omitempty"` + SatoshisPerByte float64 `json:",omitempty"` + TotalFee float64 `json:",omitempty"` +} + +type PaymentDisplay struct { + Btc string `json:",omitempty"` + Bch string `json:",omitempty"` + Eth string `json:",omitempty"` + Gusd string `json:",omitempty"` + Pax string `json:",omitempty"` + Busd string `json:",omitempty"` + Usdc string `json:",omitempty"` + Xrp string `json:",omitempty"` +} + +type ExchangeRates struct { + Btc PaymentTotals + Bch PaymentTotals + Eth PaymentTotals + Gusd PaymentTotals + Pax PaymentTotals + Busd PaymentTotals + Usdc PaymentTotals + Xrp PaymentTotals +} + +type SupportedTransactionCurrencies struct { + Btc PaymentTotals + Bch PaymentTotals + Eth PaymentTotals + Gusd PaymentTotals + Pax PaymentTotals + Busd PaymentTotals + Usdc PaymentTotals + Xrp PaymentTotals +} + +type MinerFees struct { + Btc PaymentTotals + Bch PaymentTotals + Eth PaymentTotals + Gusd PaymentTotals + Pax PaymentTotals + Busd PaymentTotals + Usdc PaymentTotals + Xrp PaymentTotals +} + // Go struct mapping the JSON returned from the BitPay server when sending a POST or GET request to /invoices. type invoice struct { @@ -140,7 +218,7 @@ type Address struct { } // CreateInvoice returns an invoice type or pass the error from the server. The method will create an invoice on the BitPay server. -func (client *Client) CreateInvoice(i Invoice) (inv invoice, err error) { +func (client *Client) CreateInvoice(i Invoice) (inv Invoice, err error) { match, _ := regexp.MatchString("^[[:upper:]]{3}$", i.Currency) if !match { err = errors.New("BitPayArgumentError: invalid currency code") @@ -150,7 +228,7 @@ func (client *Client) CreateInvoice(i Invoice) (inv invoice, err error) { i.Token = client.Token.Token response, _ := client.Post("invoices", i) body, err := ioutil.ReadAll(response.Body) - var invoice invoice + var invoice Invoice json.Unmarshal(body, &invoice) return invoice, err } From 2ef8e1aa147933ac479712430b11b86dfb72e6bc Mon Sep 17 00:00:00 2001 From: AlessandroSechi Date: Sat, 16 May 2020 12:35:28 +0200 Subject: [PATCH 06/14] Edited Create Invoice Fields --- client/client.go | 92 ++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/client/client.go b/client/client.go index 464520a..a87e6c8 100644 --- a/client/client.go +++ b/client/client.go @@ -48,29 +48,29 @@ type Invoice struct { FullNotifications string `json:",omitempty"` ExtendedNotifications string `json:",omitempty"` Physical string `json:",omitempty"` - Buyer Buyer `json:",omitempty"` + Buyer *Buyer `json:",omitempty"` PaymentCurrencies []string `json:",omitempty"` JsonPayProRequired string `json:",omitempty"` //Additional Response Fiend - Url string `json:",omitempty"` - Status string `json:",omitempty"` - InvoiceTime time.Time `json:",omitempty"` - ExpirationTime time.Time `json:",omitempty"` - CurrentTime time.Time `json:",omitempty"` - Id string `json:",omitempty"` - LowFeeDetected bool `json:",omitempty"` - AmountPaid float64 `json:",omitempty"` - DisplayAmountPaid float64 `json:",omitempty"` - ExceptionStatus bool `json:",omitempty"` - RefundAddressRequestPending bool `json:",omitempty"` - BuyerProvidedInfo Buyer `json:",omitempty"` - PaymentSubtotals PaymentTotals `json:",omitempty"` - PaymentTotals PaymentTotals `json:",omitempty"` - PaymentDisplayTotals PaymentDisplay `json:",omitempty"` - PaymentDisplaySubTotals PaymentDisplay `json:",omitempty"` - ExchangeRates ExchangeRates `json:",omitempty"` - SupportedTransactionCurrencies SupportedTransactionCurrencies `json:",omitempty"` - MinerFees MinerFees `json:",omitempty"` + Url string `json:",omitempty"` + Status string `json:",omitempty"` + InvoiceTime *time.Time `json:",omitempty"` + ExpirationTime *time.Time `json:",omitempty"` + CurrentTime *time.Time `json:",omitempty"` + Id string `json:",omitempty"` + LowFeeDetected bool `json:",omitempty"` + AmountPaid float64 `json:",omitempty"` + DisplayAmountPaid float64 `json:",omitempty"` + ExceptionStatus bool `json:",omitempty"` + RefundAddressRequestPending bool `json:",omitempty"` + BuyerProvidedInfo *Buyer `json:",omitempty"` + PaymentSubtotals *PaymentTotals `json:",omitempty"` + PaymentTotals *PaymentTotals `json:",omitempty"` + PaymentDisplayTotals *PaymentDisplay `json:",omitempty"` + PaymentDisplaySubTotals *PaymentDisplay `json:",omitempty"` + ExchangeRates *ExchangeRates `json:",omitempty"` + SupportedTransactionCurrencies *SupportedTransactionCurrencies `json:",omitempty"` + MinerFees *MinerFees `json:",omitempty"` } type Buyer struct { @@ -112,36 +112,36 @@ type PaymentDisplay struct { } type ExchangeRates struct { - Btc PaymentTotals - Bch PaymentTotals - Eth PaymentTotals - Gusd PaymentTotals - Pax PaymentTotals - Busd PaymentTotals - Usdc PaymentTotals - Xrp PaymentTotals + Btc *PaymentTotals + Bch *PaymentTotals + Eth *PaymentTotals + Gusd *PaymentTotals + Pax *PaymentTotals + Busd *PaymentTotals + Usdc *PaymentTotals + Xrp *PaymentTotals } type SupportedTransactionCurrencies struct { - Btc PaymentTotals - Bch PaymentTotals - Eth PaymentTotals - Gusd PaymentTotals - Pax PaymentTotals - Busd PaymentTotals - Usdc PaymentTotals - Xrp PaymentTotals + Btc *PaymentTotals + Bch *PaymentTotals + Eth *PaymentTotals + Gusd *PaymentTotals + Pax *PaymentTotals + Busd *PaymentTotals + Usdc *PaymentTotals + Xrp *PaymentTotals } type MinerFees struct { - Btc PaymentTotals - Bch PaymentTotals - Eth PaymentTotals - Gusd PaymentTotals - Pax PaymentTotals - Busd PaymentTotals - Usdc PaymentTotals - Xrp PaymentTotals + Btc *PaymentTotals + Bch *PaymentTotals + Eth *PaymentTotals + Gusd *PaymentTotals + Pax *PaymentTotals + Busd *PaymentTotals + Usdc *PaymentTotals + Xrp *PaymentTotals } // Go struct mapping the JSON returned from the BitPay server when sending a POST or GET request to /invoices. @@ -296,7 +296,7 @@ func (client *Client) Post(path string, paylo interface{}) (response *http.Respo } // GetInvoice is a public facade method, any client which has the ApiUri field set can retrieve an invoice from that endpoint, provided they have the invoice id. -func (client *Client) GetInvoice(invId string) (inv invoice, err error) { +func (client *Client) GetInvoice(invId string) (inv Invoice, err error) { url := client.ApiUri + "/invoices/" + invId htclient := setHttpClient(client) req, _ := http.NewRequest("GET", url, nil) @@ -375,7 +375,7 @@ func processToken(response *http.Response, jsonContents map[string]interface{}) return tok, nil } -func processInvoice(response *http.Response) (inv invoice, err error) { +func processInvoice(response *http.Response) (inv Invoice, err error) { defer response.Body.Close() contents, _ := ioutil.ReadAll(response.Body) var jsonContents map[string]interface{} From ea7a29b9797de0679d5651651d23e40411bfee63 Mon Sep 17 00:00:00 2001 From: AlessandroSechi Date: Sat, 16 May 2020 12:56:01 +0200 Subject: [PATCH 07/14] Added Create Invoice Fields --- client/client.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/client.go b/client/client.go index a87e6c8..cddcaed 100644 --- a/client/client.go +++ b/client/client.go @@ -71,6 +71,11 @@ type Invoice struct { ExchangeRates *ExchangeRates `json:",omitempty"` SupportedTransactionCurrencies *SupportedTransactionCurrencies `json:",omitempty"` MinerFees *MinerFees `json:",omitempty"` + Addresses *PaymentDisplay `json:",omitempty"` + BitcoinAddress string `json:",omitempty"` + BtcDue string `json:",omitempty"` + BtcPaid string `json:",omitempty"` + BtcPrice string `json:",omitempty"` } type Buyer struct { From ff86a6959a5dd7aac3bd4a5a70a88a2cf438e27a Mon Sep 17 00:00:00 2001 From: AlessandroSechi Date: Sat, 16 May 2020 14:39:31 +0200 Subject: [PATCH 08/14] Added JSON field names --- client/client.go | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/client/client.go b/client/client.go index cddcaed..daad0a0 100644 --- a/client/client.go +++ b/client/client.go @@ -34,30 +34,29 @@ type Token struct { } type Invoice struct { - Token string `json:",omitempty"` - Price float64 `json:",omitempty"` - Currency string `json:",omitempty"` - OrderId string `json:",omitempty"` - ItemDesc string `json:",omitempty"` - ItemCode string `json:",omitempty"` - NotificationEmail string `json:",omitempty"` - NotificationUrl string `json:",omitempty"` - RedirectUrl string `json:",omitempty"` - PosData string `json:",omitempty"` - TransactionSpeed string `json:",omitempty"` - FullNotifications string `json:",omitempty"` - ExtendedNotifications string `json:",omitempty"` - Physical string `json:",omitempty"` - Buyer *Buyer `json:",omitempty"` - PaymentCurrencies []string `json:",omitempty"` + Token string `json:"token,omitempty"` + Price float64 `json:"price,omitempty"` + Currency string `json:"currency,omitempty"` + OrderId string `json:"order,omitempty"` + ItemDesc string `json:"itemDesc,omitempty"` + ItemCode string `json:"itemCode,omitempty"` + NotificationEmail string `json:"notificationEmail,omitempty"` + NotificationUrl string `json:"notificationUrl,omitempty"` + RedirectUrl string `json:"redirectUrl,omitempty"` + PosData string `json:"posData,omitempty"` + TransactionSpeed string `json:"transactionSpeed,omitempty"` + FullNotifications string `json:"fullNotifications,omitempty"` + ExtendedNotifications string `json:"extendedNotifications,omitempty"` + Physical string `json:"physical,omitempty"` + Buyer *Buyer `json:"buyer,omitempty"` + PaymentCurrencies []string `json:"paymentCurrencies,omitempty"` JsonPayProRequired string `json:",omitempty"` //Additional Response Fiend - Url string `json:",omitempty"` - Status string `json:",omitempty"` + Url string `json:"url,omitempty"` + Status string `json:"status,omitempty"` InvoiceTime *time.Time `json:",omitempty"` ExpirationTime *time.Time `json:",omitempty"` CurrentTime *time.Time `json:",omitempty"` - Id string `json:",omitempty"` LowFeeDetected bool `json:",omitempty"` AmountPaid float64 `json:",omitempty"` DisplayAmountPaid float64 `json:",omitempty"` @@ -73,9 +72,10 @@ type Invoice struct { MinerFees *MinerFees `json:",omitempty"` Addresses *PaymentDisplay `json:",omitempty"` BitcoinAddress string `json:",omitempty"` - BtcDue string `json:",omitempty"` - BtcPaid string `json:",omitempty"` - BtcPrice string `json:",omitempty"` + BtcDue string `json:"btcDue,omitempty"` + BtcPaid string `json:"btcPaid,omitempty"` + BtcPrice string `json:"btcPrice,omitempty"` + Id string `json:"id,omitempty"` } type Buyer struct { From 82a37a97d639045096a0f1f62d89973d338b77da Mon Sep 17 00:00:00 2001 From: AlessandroSechi Date: Sat, 16 May 2020 16:53:48 +0200 Subject: [PATCH 09/14] Edited Invoice --- client/client.go | 222 +++++++++++++++++++++++------------------------ 1 file changed, 109 insertions(+), 113 deletions(-) diff --git a/client/client.go b/client/client.go index daad0a0..60b55b2 100644 --- a/client/client.go +++ b/client/client.go @@ -34,119 +34,115 @@ type Token struct { } type Invoice struct { - Token string `json:"token,omitempty"` - Price float64 `json:"price,omitempty"` - Currency string `json:"currency,omitempty"` - OrderId string `json:"order,omitempty"` - ItemDesc string `json:"itemDesc,omitempty"` - ItemCode string `json:"itemCode,omitempty"` - NotificationEmail string `json:"notificationEmail,omitempty"` - NotificationUrl string `json:"notificationUrl,omitempty"` - RedirectUrl string `json:"redirectUrl,omitempty"` - PosData string `json:"posData,omitempty"` - TransactionSpeed string `json:"transactionSpeed,omitempty"` - FullNotifications string `json:"fullNotifications,omitempty"` - ExtendedNotifications string `json:"extendedNotifications,omitempty"` - Physical string `json:"physical,omitempty"` - Buyer *Buyer `json:"buyer,omitempty"` - PaymentCurrencies []string `json:"paymentCurrencies,omitempty"` - JsonPayProRequired string `json:",omitempty"` - //Additional Response Fiend - Url string `json:"url,omitempty"` - Status string `json:"status,omitempty"` - InvoiceTime *time.Time `json:",omitempty"` - ExpirationTime *time.Time `json:",omitempty"` - CurrentTime *time.Time `json:",omitempty"` - LowFeeDetected bool `json:",omitempty"` - AmountPaid float64 `json:",omitempty"` - DisplayAmountPaid float64 `json:",omitempty"` - ExceptionStatus bool `json:",omitempty"` - RefundAddressRequestPending bool `json:",omitempty"` - BuyerProvidedInfo *Buyer `json:",omitempty"` - PaymentSubtotals *PaymentTotals `json:",omitempty"` - PaymentTotals *PaymentTotals `json:",omitempty"` - PaymentDisplayTotals *PaymentDisplay `json:",omitempty"` - PaymentDisplaySubTotals *PaymentDisplay `json:",omitempty"` - ExchangeRates *ExchangeRates `json:",omitempty"` - SupportedTransactionCurrencies *SupportedTransactionCurrencies `json:",omitempty"` - MinerFees *MinerFees `json:",omitempty"` - Addresses *PaymentDisplay `json:",omitempty"` - BitcoinAddress string `json:",omitempty"` - BtcDue string `json:"btcDue,omitempty"` - BtcPaid string `json:"btcPaid,omitempty"` - BtcPrice string `json:"btcPrice,omitempty"` - Id string `json:"id,omitempty"` -} - -type Buyer struct { - Name string `json:",omitempty"` - Address1 string `json:",omitempty"` - Address2 string `json:",omitempty"` - Locality string `json:",omitempty"` - Region string `json:",omitempty"` - PostalCode string `json:",omitempty"` - Country string `json:",omitempty"` - Email string `json:",omitempty"` - Phone string `json:",omitempty"` - Notify bool `json:",omitempty"` -} - -type PaymentTotals struct { - Btc float64 `json:",omitempty"` - Bch float64 `json:",omitempty"` - Eth float64 `json:",omitempty"` - Gusd float64 `json:",omitempty"` - Pax float64 `json:",omitempty"` - Busd float64 `json:",omitempty"` - Usdc float64 `json:",omitempty"` - Xrp float64 `json:",omitempty"` - Enabled bool `json:",omitempty"` - SatoshisPerByte float64 `json:",omitempty"` - TotalFee float64 `json:",omitempty"` -} - -type PaymentDisplay struct { - Btc string `json:",omitempty"` - Bch string `json:",omitempty"` - Eth string `json:",omitempty"` - Gusd string `json:",omitempty"` - Pax string `json:",omitempty"` - Busd string `json:",omitempty"` - Usdc string `json:",omitempty"` - Xrp string `json:",omitempty"` -} - -type ExchangeRates struct { - Btc *PaymentTotals - Bch *PaymentTotals - Eth *PaymentTotals - Gusd *PaymentTotals - Pax *PaymentTotals - Busd *PaymentTotals - Usdc *PaymentTotals - Xrp *PaymentTotals -} - -type SupportedTransactionCurrencies struct { - Btc *PaymentTotals - Bch *PaymentTotals - Eth *PaymentTotals - Gusd *PaymentTotals - Pax *PaymentTotals - Busd *PaymentTotals - Usdc *PaymentTotals - Xrp *PaymentTotals -} - -type MinerFees struct { - Btc *PaymentTotals - Bch *PaymentTotals - Eth *PaymentTotals - Gusd *PaymentTotals - Pax *PaymentTotals - Busd *PaymentTotals - Usdc *PaymentTotals - Xrp *PaymentTotals + Addresses struct { + BTC string `json:"BTC"` + } `json:"addresses"` + AmountPaid int `json:"amountPaid"` + BitcoinAddress string `json:"bitcoinAddress"` + BtcDue string `json:"btcDue"` + BtcPaid string `json:"btcPaid"` + BtcPrice string `json:"btcPrice"` + Buyer struct { + Address1 interface{} `json:"address1"` + Address2 interface{} `json:"address2"` + Country interface{} `json:"country"` + Email interface{} `json:"email"` + Locality interface{} `json:"locality"` + Name interface{} `json:"name"` + Phone interface{} `json:"phone"` + PostalCode interface{} `json:"postalCode"` + Region interface{} `json:"region"` + } `json:"buyer"` + BuyerPaidBtcMinerFee interface{} `json:"buyerPaidBtcMinerFee"` + BuyerTotalBtcAmount interface{} `json:"buyerTotalBtcAmount"` + CryptoInfo []struct { + Address string `json:"address"` + CryptoCode string `json:"cryptoCode"` + CryptoPaid string `json:"cryptoPaid"` + Due string `json:"due"` + ExRates struct { + USD int `json:"USD"` + } `json:"exRates"` + NetworkFee string `json:"networkFee"` + Paid string `json:"paid"` + PaymentType string `json:"paymentType"` + PaymentUrls struct { + BIP21 string `json:"BIP21"` + BIP72 interface{} `json:"BIP72"` + BIP72B interface{} `json:"BIP72b"` + BIP73 interface{} `json:"BIP73"` + BOLT11 interface{} `json:"BOLT11"` + } `json:"paymentUrls"` + Payments []interface{} `json:"payments"` + Price string `json:"price"` + Rate float64 `json:"rate"` + TotalDue string `json:"totalDue"` + TxCount int `json:"txCount"` + URL string `json:"url"` + } `json:"cryptoInfo"` + Currency string `json:"currency"` + CurrentTime int64 `json:"currentTime"` + ExRates struct { + USD int `json:"USD"` + } `json:"exRates"` + ExceptionStatus bool `json:"exceptionStatus"` + ExchangeRates struct { + BTC struct { + USD int `json:"USD"` + } `json:"BTC"` + } `json:"exchangeRates"` + ExpirationTime int64 `json:"expirationTime"` + Flags struct { + Refundable bool `json:"refundable"` + } `json:"flags"` + GUID string `json:"guid"` + ID string `json:"id"` + InvoiceTime int64 `json:"invoiceTime"` + ItemCode interface{} `json:"itemCode"` + ItemDesc interface{} `json:"itemDesc"` + LowFeeDetected bool `json:"lowFeeDetected"` + MinerFees struct { + BTC struct { + SatoshisPerByte int `json:"satoshisPerByte"` + TotalFee int `json:"totalFee"` + } `json:"BTC"` + } `json:"minerFees"` + OrderID interface{} `json:"orderId"` + PaymentCodes struct { + BTC struct { + BIP21 string `json:"BIP21"` + BIP72 interface{} `json:"BIP72"` + BIP72B interface{} `json:"BIP72b"` + BIP73 interface{} `json:"BIP73"` + BOLT11 interface{} `json:"BOLT11"` + } `json:"BTC"` + } `json:"paymentCodes"` + PaymentSubtotals struct { + BTC int `json:"BTC"` + } `json:"paymentSubtotals"` + PaymentTotals struct { + BTC int `json:"BTC"` + } `json:"paymentTotals"` + PaymentUrls struct { + BIP21 string `json:"BIP21"` + BIP72 interface{} `json:"BIP72"` + BIP72B interface{} `json:"BIP72b"` + BIP73 interface{} `json:"BIP73"` + BOLT11 interface{} `json:"BOLT11"` + } `json:"paymentUrls"` + PosData interface{} `json:"posData"` + Price int `json:"price"` + Rate float64 `json:"rate"` + RefundAddressRequestPending bool `json:"refundAddressRequestPending"` + Status string `json:"status"` + SupportedTransactionCurrencies struct { + BTC struct { + Enabled bool `json:"enabled"` + Reason interface{} `json:"reason"` + } `json:"BTC"` + } `json:"supportedTransactionCurrencies"` + Token string `json:"token"` + URL string `json:"url"` } // Go struct mapping the JSON returned from the BitPay server when sending a POST or GET request to /invoices. From 6d4adadec3307e5c66f98c120bf107f969d9f035 Mon Sep 17 00:00:00 2001 From: AlessandroSechi Date: Sat, 16 May 2020 17:23:22 +0200 Subject: [PATCH 10/14] Finally Working --- client/client.go | 223 ++++++++++++++++++++++++++--------------------- 1 file changed, 123 insertions(+), 100 deletions(-) diff --git a/client/client.go b/client/client.go index 60b55b2..0700bc3 100644 --- a/client/client.go +++ b/client/client.go @@ -34,115 +34,139 @@ type Token struct { } type Invoice struct { - Addresses struct { - BTC string `json:"BTC"` - } `json:"addresses"` - AmountPaid int `json:"amountPaid"` - BitcoinAddress string `json:"bitcoinAddress"` - BtcDue string `json:"btcDue"` - BtcPaid string `json:"btcPaid"` - BtcPrice string `json:"btcPrice"` - Buyer struct { - Address1 interface{} `json:"address1"` - Address2 interface{} `json:"address2"` - Country interface{} `json:"country"` - Email interface{} `json:"email"` - Locality interface{} `json:"locality"` - Name interface{} `json:"name"` - Phone interface{} `json:"phone"` - PostalCode interface{} `json:"postalCode"` - Region interface{} `json:"region"` - } `json:"buyer"` - BuyerPaidBtcMinerFee interface{} `json:"buyerPaidBtcMinerFee"` - BuyerTotalBtcAmount interface{} `json:"buyerTotalBtcAmount"` + Addresses *PaymentDisplay `json:"addresses,omitempty"` + AmountPaid int `json:"amountPaid,omitempty"` + BitcoinAddress string `json:"bitcoinAddress,omitempty"` + BtcDue string `json:"btcDue,omitempty"` + BtcPaid string `json:"btcPaid,omitempty"` + BtcPrice string `json:"btcPrice,omitempty"` + Buyer *Buyer `json:"buyer,omitempty"` + BuyerPaidBtcMinerFee interface{} `json:"buyerPaidBtcMinerFee,omitempty"` + BuyerTotalBtcAmount interface{} `json:"buyerTotalBtcAmount,omitempty"` CryptoInfo []struct { - Address string `json:"address"` - CryptoCode string `json:"cryptoCode"` - CryptoPaid string `json:"cryptoPaid"` - Due string `json:"due"` + Address string `json:"address,omitempty"` + CryptoCode string `json:"cryptoCode,omitempty"` + CryptoPaid string `json:"cryptoPaid,omitempty"` + Due string `json:"due,omitempty"` ExRates struct { - USD int `json:"USD"` - } `json:"exRates"` - NetworkFee string `json:"networkFee"` - Paid string `json:"paid"` - PaymentType string `json:"paymentType"` + USD int `json:"USD,omitempty"` + } `json:"exRates,omitempty"` + NetworkFee string `json:"networkFee,omitempty"` + Paid string `json:"paid,omitempty"` + PaymentType string `json:"paymentType,omitempty"` PaymentUrls struct { - BIP21 string `json:"BIP21"` - BIP72 interface{} `json:"BIP72"` - BIP72B interface{} `json:"BIP72b"` - BIP73 interface{} `json:"BIP73"` - BOLT11 interface{} `json:"BOLT11"` - } `json:"paymentUrls"` - Payments []interface{} `json:"payments"` - Price string `json:"price"` - Rate float64 `json:"rate"` - TotalDue string `json:"totalDue"` - TxCount int `json:"txCount"` - URL string `json:"url"` - } `json:"cryptoInfo"` - Currency string `json:"currency"` - CurrentTime int64 `json:"currentTime"` - ExRates struct { - USD int `json:"USD"` - } `json:"exRates"` - ExceptionStatus bool `json:"exceptionStatus"` - ExchangeRates struct { - BTC struct { - USD int `json:"USD"` - } `json:"BTC"` - } `json:"exchangeRates"` - ExpirationTime int64 `json:"expirationTime"` - Flags struct { - Refundable bool `json:"refundable"` - } `json:"flags"` - GUID string `json:"guid"` - ID string `json:"id"` - InvoiceTime int64 `json:"invoiceTime"` - ItemCode interface{} `json:"itemCode"` - ItemDesc interface{} `json:"itemDesc"` - LowFeeDetected bool `json:"lowFeeDetected"` - MinerFees struct { + BIP21 string `json:"BIP21,omitempty"` + BIP72 interface{} `json:"BIP72,omitempty"` + BIP72B interface{} `json:"BIP72b,omitempty"` + BIP73 interface{} `json:"BIP73,omitempty"` + BOLT11 interface{} `json:"BOLT11,omitempty"` + } `json:"paymentUrls,omitempty"` + Payments []interface{} `json:"payments,omitempty"` + Price string `json:"price,omitempty"` + Rate float64 `json:"rate,omitempty"` + TotalDue string `json:"totalDue,omitempty"` + TxCount int `json:"txCount,omitempty"` + URL string `json:"url,omitempty"` + } `json:"cryptoInfo,omitempty"` + Currency string `json:"currency,omitempty"` + CurrentTime int64 `json:"currentTime,omitempty"` + /* + ExRates struct { + USD int `json:"USD,omitempty"` + } `json:"exRates,omitempty"` + */ + + ExceptionStatus bool `json:"exceptionStatus,omitempty"` + /* + ExchangeRates struct { + BTC struct { + USD int `json:"USD,omitempty"` + } `json:"BTC,omitempty"` + } `json:"exchangeRates,omitempty"` + */ + + ExpirationTime int64 `json:"expirationTime,omitempty"` + /* + Flags struct { + Refundable bool `json:"refundable,omitempty"` + } `json:"flags,omitempty"` + */ + GUID string `json:"guid,omitempty"` + ID string `json:"id,omitempty"` + InvoiceTime int64 `json:"invoiceTime,omitempty"` + ItemCode interface{} `json:"itemCode,omitempty"` + ItemDesc interface{} `json:"itemDesc,omitempty"` + LowFeeDetected bool `json:"lowFeeDetected,omitempty"` + /*MinerFees struct { BTC struct { - SatoshisPerByte int `json:"satoshisPerByte"` - TotalFee int `json:"totalFee"` - } `json:"BTC"` - } `json:"minerFees"` - OrderID interface{} `json:"orderId"` - PaymentCodes struct { + SatoshisPerByte int `json:"satoshisPerByte,omitempty"` + TotalFee int `json:"totalFee,omitempty"` + } `json:"BTC,omitempty"` + } `json:"minerFees,omitempty"` + */ + OrderID interface{} `json:"orderId,omitempty"` + /*PaymentCodes struct { BTC struct { - BIP21 string `json:"BIP21"` - BIP72 interface{} `json:"BIP72"` - BIP72B interface{} `json:"BIP72b"` - BIP73 interface{} `json:"BIP73"` - BOLT11 interface{} `json:"BOLT11"` - } `json:"BTC"` - } `json:"paymentCodes"` - PaymentSubtotals struct { - BTC int `json:"BTC"` - } `json:"paymentSubtotals"` + BIP21 string `json:"BIP21,omitempty"` + BIP72 interface{} `json:"BIP72,omitempty"` + BIP72B interface{} `json:"BIP72b,omitempty"` + BIP73 interface{} `json:"BIP73,omitempty"` + BOLT11 interface{} `json:"BOLT11,omitempty"` + } `json:"BTC,omitempty"` + } `json:"paymentCodes,omitempty"` + */ + /*PaymentSubtotals struct { + BTC int `json:"BTC,omitempty"` + } `json:"paymentSubtotals,omitempty"` PaymentTotals struct { - BTC int `json:"BTC"` - } `json:"paymentTotals"` + BTC int `json:"BTC,omitempty"` + } `json:"paymentTotals,omitempty"` PaymentUrls struct { - BIP21 string `json:"BIP21"` - BIP72 interface{} `json:"BIP72"` - BIP72B interface{} `json:"BIP72b"` - BIP73 interface{} `json:"BIP73"` - BOLT11 interface{} `json:"BOLT11"` - } `json:"paymentUrls"` - PosData interface{} `json:"posData"` - Price int `json:"price"` - Rate float64 `json:"rate"` - RefundAddressRequestPending bool `json:"refundAddressRequestPending"` - Status string `json:"status"` - SupportedTransactionCurrencies struct { + BIP21 string `json:"BIP21,omitempty"` + BIP72 interface{} `json:"BIP72,omitempty"` + BIP72B interface{} `json:"BIP72b,omitempty"` + BIP73 interface{} `json:"BIP73,omitempty"` + BOLT11 interface{} `json:"BOLT11,omitempty"` + } `json:"paymentUrls,omitempty"` + */ + PosData interface{} `json:"posData,omitempty"` + Price float64 `json:"price,omitempty"` + Rate float64 `json:"rate,omitempty"` + RefundAddressRequestPending bool `json:"refundAddressRequestPending,omitempty"` + Status string `json:"status,omitempty"` + /*SupportedTransactionCurrencies struct { BTC struct { Enabled bool `json:"enabled"` Reason interface{} `json:"reason"` } `json:"BTC"` - } `json:"supportedTransactionCurrencies"` - Token string `json:"token"` - URL string `json:"url"` + } `json:"supportedTransactionCurrencies,omitempty"` + */ + PaymentCurrencies []string `json:"paymentCurrencies,omitempty"` + Token string `json:"token,omitempty"` + URL string `json:"url,omitempty"` +} + +type PaymentDisplay struct { + Btc string `json:"BTC,omitempty"` + Bch string `json:"BCH,omitempty"` + Eth string `json:"ETH,omitempty"` + Gusd string `json:"GUSD,omitempty"` + Pax string `json:"PAX,omitempty"` + Busd string `json:"BUSD,omitempty"` + Usdc string `json:"USDC,omitempty"` + Xrp string `json:"XRP,omitempty"` +} + +type Buyer struct { + Address1 interface{} `json:"address1,omitempty"` + Address2 interface{} `json:"address2,omitempty"` + Country interface{} `json:"country,omitempty"` + Email interface{} `json:"email,omitempty"` + Locality interface{} `json:"locality,omitempty"` + Name interface{} `json:"name,omitempty"` + Phone interface{} `json:"phone,omitempty"` + PostalCode interface{} `json:"postalCode,omitempty"` + Region interface{} `json:"region,omitempty"` } // Go struct mapping the JSON returned from the BitPay server when sending a POST or GET request to /invoices. @@ -228,9 +252,8 @@ func (client *Client) CreateInvoice(i Invoice) (inv Invoice, err error) { i.Token = client.Token.Token response, _ := client.Post("invoices", i) - body, err := ioutil.ReadAll(response.Body) var invoice Invoice - json.Unmarshal(body, &invoice) + invoice, err = processInvoice(response) return invoice, err } From 9c3c7510cd68aeef1dce870ac70c24416a9ef582 Mon Sep 17 00:00:00 2001 From: AlessandroSechi Date: Sun, 13 Dec 2020 17:05:30 +0100 Subject: [PATCH 11/14] FixContentError --- client/client.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/client/client.go b/client/client.go index 0700bc3..71f9eda 100644 --- a/client/client.go +++ b/client/client.go @@ -388,7 +388,12 @@ func setHttpClient(client *Client) *http.Client { func processErrorMessage(response *http.Response, jsonContents map[string]interface{}) error { responseStatus := strconv.Itoa(response.StatusCode) - contentError := responseStatus + ": " + jsonContents["error"].(string) + var contentError string + if jsonContents != nil { + contentError = responseStatus + ": " + jsonContents["error"].(string) + } else { + contentError = responseStatus + } return errors.New(contentError) } From 5cc4a507dfff6063e3c4c3be9fd5cf3fcb003a56 Mon Sep 17 00:00:00 2001 From: AlessandroSechi Date: Sun, 13 Dec 2020 22:54:59 +0100 Subject: [PATCH 12/14] FixContentError --- client/client.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/client.go b/client/client.go index 71f9eda..9d2778e 100644 --- a/client/client.go +++ b/client/client.go @@ -348,7 +348,10 @@ func (client *Client) GetTokens() (tokes []map[string]string, err error) { req.Header.Add("X-Signature", sig) response, _ := htclient.Do(req) defer response.Body.Close() - contents, _ := ioutil.ReadAll(response.Body) + contents, err := ioutil.ReadAll(response.Body) + if err != nil { + return tokes, err + } var jsonContents map[string]interface{} json.Unmarshal(contents, &jsonContents) if response.StatusCode/100 != 2 { From bacc1cf0869c2ffc1c3495b5ccb728a212d7086c Mon Sep 17 00:00:00 2001 From: AlessandroSechi Date: Sun, 13 Dec 2020 23:00:06 +0100 Subject: [PATCH 13/14] FixContentError --- client/client.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/client.go b/client/client.go index 9d2778e..102b12b 100644 --- a/client/client.go +++ b/client/client.go @@ -346,7 +346,10 @@ func (client *Client) GetTokens() (tokes []map[string]string, err error) { req.Header.Add("X-Identity", publ) sig := ku.Sign(url, client.Pem) req.Header.Add("X-Signature", sig) - response, _ := htclient.Do(req) + response, err := htclient.Do(req) + if err != nil { + return tokes, err + } defer response.Body.Close() contents, err := ioutil.ReadAll(response.Body) if err != nil { From 634028e1d77ffece545e178b291e4031935313ac Mon Sep 17 00:00:00 2001 From: AlessandroSechi Date: Sun, 13 Dec 2020 23:07:19 +0100 Subject: [PATCH 14/14] FixContentError --- client/client.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/client.go b/client/client.go index 102b12b..449bd75 100644 --- a/client/client.go +++ b/client/client.go @@ -330,7 +330,10 @@ func (client *Client) GetInvoice(invId string) (inv Invoice, err error) { req.Header.Add("X-Identity", publ) sig := ku.Sign(url, client.Pem) req.Header.Add("X-Signature", sig) - response, _ := htclient.Do(req) + response, err := htclient.Do(req) + if err != nil { + return inv, err + } inv, err = processInvoice(response) return inv, err }