btcpay

package module
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 1, 2024 License: CC0-1.0 Imports: 13 Imported by: 4

README

btcpay

A simple Go (golang) library for parts of the BTCPay Greenfield API (v1). See the docs at pkg.go.dev.

Known issues

The BTCPay Greenfield API provides no way to get the real amount which has been paid. Use the BitPay API for that.

License

This work is dual-licensed under Unlicense and CC0. You can choose between one of them if you use this work.

Documentation

Overview

Package btcpay implements part of the BTCPay Server Greenfield API v1.

Index

Constants

View Source
const (
	InvoiceNew        string = "New"
	InvoiceProcessing string = "Processing"
	InvoiceExpired    string = "Expired"
	InvoiceInvalid    string = "Invalid"
	InvoiceSettled    string = "Settled"
)

Variables

View Source
var ErrBadRequest = errors.New("bad request")
View Source
var ErrNotFound = errors.New("not found")
View Source
var ErrUnauthenticated = errors.New("unauthenticated")
View Source
var ErrUnauthorized = errors.New("unauthorized")

Functions

func Create added in v0.3.0

func Create(jsonPath string) error

Create creates an empty json config file with empty values and chmod 600, so someone can fill in easily. Create always returns an error.

func ValidateRate added in v0.4.2

func ValidateRate(methods []InvoicePaymentMethod, cryptoCode string, maxRate float64) error

ValidateRates returns an error if the exchange rate for the given cryptoCode is above the max rate.

Types

type DummyStore added in v0.2.0

type DummyStore struct {
	Invoices map[string]*Invoice
}

DummyStore is designed for testing only. It supports invoices only and is not thread-safe.

func NewDummyStore added in v0.2.0

func NewDummyStore() *DummyStore

func (*DummyStore) CheckInvoiceAuth added in v0.3.0

func (*DummyStore) CheckInvoiceAuth() error

func (*DummyStore) CreateInvoice added in v0.2.0

func (s *DummyStore) CreateInvoice(req *InvoiceRequest) (*Invoice, error)

func (*DummyStore) CreatePaymentRequest added in v0.2.0

func (*DummyStore) CreatePaymentRequest(req *PaymentRequestRequest) (*PaymentRequest, error)

func (*DummyStore) GetInvoice added in v0.2.0

func (s *DummyStore) GetInvoice(id string) (*Invoice, error)

func (*DummyStore) GetPaymentRequest added in v0.2.0

func (*DummyStore) GetPaymentRequest(id string) (*PaymentRequest, error)

func (*DummyStore) GetServerStatus added in v0.3.0

func (*DummyStore) GetServerStatus() (*ServerStatus, error)
func (*DummyStore) InvoiceCheckoutLink(id string) string

func (*DummyStore) InvoiceCheckoutLinkPreferOnion added in v0.4.0

func (*DummyStore) InvoiceCheckoutLinkPreferOnion(id string) string
func (*DummyStore) PaymentRequestLink(id string) string

func (*DummyStore) PaymentRequestLinkPreferOnion added in v0.4.0

func (*DummyStore) PaymentRequestLinkPreferOnion(id string) string

func (*DummyStore) ProcessWebhook added in v0.2.0

func (*DummyStore) ProcessWebhook(r *http.Request) (*InvoiceEvent, error)

type EventType

type EventType string
const (
	EventInvoiceCreated         EventType = "InvoiceCreated"
	EventInvoiceExpired         EventType = "InvoiceExpired"
	EventInvoiceInvalid         EventType = "InvoiceInvalid"
	EventInvoicePaymentSettled  EventType = "InvoicePaymentSettled"
	EventInvoiceProcessing      EventType = "InvoiceProcessing"
	EventInvoiceReceivedPayment EventType = "InvoiceReceivedPayment"
	EventInvoiceSettled         EventType = "InvoiceSettled"
)

An invoice is considered "settled" if it has been "paid" in time (seen on the blockchain before the invoice time expired) and the full amount has been paid and the transaction has been confirmed (got n confirmations on the blockchain, see SpeedPolicy).

type Invoice

type Invoice struct {
	InvoiceRequest
	ID                   string `json:"id"`
	CheckoutLink         string `json:"checkoutLink"`
	CreatedTime          int64  `json:"createdTime"`
	ExpirationTime       int64  `json:"expirationTime"`
	MonitoringExpiration int64  `json:"monitoringExpiration"`
	Status               string `json:"status"`
	AdditionalStatus     string `json:"additionalStatus"`
}

type InvoiceCheckout

type InvoiceCheckout struct {
	SpeedPolicy       SpeedPolicy `json:"speedPolicy,omitempty"` // default: store setting
	PaymentMethods    []string    `json:"paymentMethods,omitempty"`
	ExpirationMinutes int         `json:"expirationMinutes,omitempty"` // refers to the "paid" state, when the transaction becomes visible on the blockchain
	MonitoringMinutes int         `json:"monitoringMinutes,omitempty"`
	PaymentTolerance  float64     `json:"paymentTolerance,omitempty"`
	RedirectURL       string      `json:"redirectURL,omitempty"`     // RedirectURL is stored in the invoice list of your BTCPay server and used as href behind OrderID.
	DefaultLanguage   string      `json:"defaultLanguage,omitempty"` // see https://github.com/btcpayserver/btcpayserver/tree/master/BTCPayServer/wwwroot/locales
}

type InvoiceEvent

type InvoiceEvent struct {
	DeliveryID         string          `json:"deliveryId"`
	InvoiceID          string          `json:"invoiceId"`
	IsRedelivery       bool            `json:"isRedelivery"`
	OriginalDeliveryID string          `json:"originalDeliveryId"`
	StoreID            string          `json:"storeId"`
	Timestamp          int64           `json:"timestamp"`
	Type               EventType       `json:"type"`
	WebhookID          string          `json:"webhookId"`
	InvoiceMetadata    InvoiceMetadata `json:"metadata"`

	// InvoiceInvalid and InvoiceSettled only
	ManuallyMarked bool `json:"manuallyMarked"`

	// InvoiceReceivedPayment only
	AfterExpiration bool `json:"afterExpiration"` // whether this payment has been sent after the invoice expired

	// InvoiceExpired only
	PartiallyPaid bool `json:"partiallyPaid"`

	// InvoiceProcessing only
	OverPaid bool `json:"overPaid"`
}

An InvoiceEvent is sent by a webhook. You can find your custom OrderID in InvoiceMetadata or use GetInvoice to obtain the full invoice.

type InvoiceMetadata

type InvoiceMetadata struct {
	OrderID string `json:"orderId,omitempty"` // OrderID is stored in the invoice list of your BTCPay server. If the invoice has been created through a payment request, this is the ID of the payment request.
}

type InvoicePaymentMethod added in v0.4.2

type InvoicePaymentMethod struct {
	PaymentMethod     string `json:"paymentMethod"` // example: "XMR"
	CryptoCode        string `json:"cryptoCode"`    // example: "XMR"
	Destination       string `json:"destination"`
	PaymentLink       string `json:"paymentLink"`
	Rate              string `json:"rate"`              // example: "122.7738548555"
	PaymentMethodPaid string `json:"paymentMethodPaid"` // example: "0.03665275"
	TotalPaid         string `json:"totalPaid"`         // Total invoice payment, converted into this currency. This is greater than zero even if there is no payment in this crypto. Be careful!
	Due               string `json:"due"`               // example: "0"
	Amount            string `json:"amount"`            // Some amount, converted into this currency. This is greater than zero even if there is no payment in this crypto. Be careful!
	NetworkFee        string `json:"networkFee"`
	Payments          []struct {
		ID           string `json:"id"`
		ReceivedDate int    `json:"receivedDate"` // unix timestamp
		Value        string `json:"value"`        // example: "0.036652750000"
		Fee          string `json:"fee"`          // example: "0.0000000003"
		Status       string `json:"status"`       // example: "Settled"
		Destination  string `json:"destination"`
	} `json:"payments"`
	Activated      bool `json:"activated"`
	AdditionalData struct {
		ProvidedComment          string `json:"providedComment"`
		ConsumedLightningAddress string `json:"consumedLightningAddress"`
	} `json:"additionalData"`
}

type InvoiceRequest

type InvoiceRequest struct {
	Amount          float64 `json:"amount,string"`
	Currency        string  `json:"currency"`
	InvoiceMetadata `json:"metadata,omitempty"`
	InvoiceCheckout `json:"checkout,omitempty"`
}

type PaymentRequest

type PaymentRequest struct {
	PaymentRequestRequest
	Archived bool                 `json:"archived"`
	Created  string               `json:"created"`
	ID       string               `json:"id"`
	Status   PaymentRequestStatus `json:"status"`
}

type PaymentRequestRequest

type PaymentRequestRequest struct {
	AllowCustomPaymentAmounts bool    `json:"allowCustomPaymentAmounts,omitempty"`
	Amount                    float64 `json:"amount"`
	Currency                  string  `json:"currency"`                // ISO 4217 Currency code (BTC, EUR, USD, etc)
	CustomCSSLink             string  `json:"customCSSLink,omitempty"` // URI
	Description               string  `json:"description,omitempty"`   // HTML
	Email                     string  `json:"email,omitempty"`
	EmbeddedCSS               string  `json:"embeddedCSS,omitempty"` // CSS up to 500 bytes
	ExpiryDate                string  `json:"expiryDate,omitempty"`  // RFC3339 date (in contrast to the docs which say int64)
	Title                     string  `json:"title"`                 // required
}

Mandatory fields are amount, currency and title.

func (*PaymentRequestRequest) SetExpiryDays

func (req *PaymentRequestRequest) SetExpiryDays(days int)

type PaymentRequestStatus

type PaymentRequestStatus string
const (
	PaymentRequestPending   PaymentRequestStatus = "Pending"
	PaymentRequestCompleted PaymentRequestStatus = "Completed"
	PaymentRequestExpired   PaymentRequestStatus = "Expired"
)

type ServerStatus added in v0.3.0

type ServerStatus struct {
	Version                 string       `json:"version"`
	Onion                   string       `json:"onion"`
	SupportedPaymentMethods []string     `json:"supportedPaymentMethods"`
	FullySynched            bool         `json:"fullySynched"`
	SyncStatuses            []SyncStatus `json:"syncStatus"`
}

type ServerStore added in v0.2.0

type ServerStore struct {
	Host          string             `json:"uri"`        // without "/api" and without trailing slash, used for API access and user links
	HostOnion     string             `json:"onion"`      // without "/api" and without trailing slash, used for user links only, can be empty
	UserAPIKey    string             `json:"userAPIKey"` // to be created in the BTCPay Server user settings (not in the store settings)
	ID            string             `json:"id"`
	WebhookSecret string             `json:"webhookSecret"`
	MaxRates      map[string]float64 `json:"maxRates"` // example: {"XMR": 1000, "BTC": 500000}
}

func Load added in v0.3.0

func Load(jsonPath string) (*ServerStore, error)

Load unmarshals a json config file into a ServerStore. If the file doesn't exist, it is created and an error is returned.

func (*ServerStore) CheckInvoiceAuth added in v0.3.0

func (s *ServerStore) CheckInvoiceAuth() error

CheckInvoiceAuth checks authentication and authorization by performing bogus CreateInvoice and GetInvoice calls and checking the result. It returns ErrUnauthenticated, ErrUnauthorized or nil.

func (*ServerStore) CreateInvoice added in v0.2.0

func (s *ServerStore) CreateInvoice(req *InvoiceRequest) (*Invoice, error)

CreateInvoice creates an invoice which can be paid by the customer. It is recommended to set InvoiceRequest.InvoiceMetadata.OrderID in order to identify the order in both a webhook and in your bookkeeping. Alternatively you can store the btcpay invoice ID in your order database.

func (*ServerStore) CreatePaymentRequest added in v0.2.0

func (s *ServerStore) CreatePaymentRequest(req *PaymentRequestRequest) (*PaymentRequest, error)

func (*ServerStore) GetInvoice added in v0.2.0

func (s *ServerStore) GetInvoice(id string) (*Invoice, error)

func (*ServerStore) GetInvoicePaymentMethods added in v0.4.2

func (s *ServerStore) GetInvoicePaymentMethods(id string) ([]InvoicePaymentMethod, error)

func (*ServerStore) GetPaymentRequest added in v0.2.0

func (s *ServerStore) GetPaymentRequest(id string) (*PaymentRequest, error)

func (*ServerStore) GetServerStatus added in v0.3.0

func (s *ServerStore) GetServerStatus() (*ServerStatus, error)

GetServerStatus requires successful authentication, but no specific permissions.

func (s *ServerStore) InvoiceCheckoutLink(id string) string

func (*ServerStore) InvoiceCheckoutLinkPreferOnion added in v0.4.0

func (s *ServerStore) InvoiceCheckoutLinkPreferOnion(id string) string
func (s *ServerStore) PaymentRequestLink(id string) string

func (*ServerStore) PaymentRequestLinkPreferOnion added in v0.4.0

func (s *ServerStore) PaymentRequestLinkPreferOnion(id string) string

func (*ServerStore) ProcessWebhook added in v0.2.0

func (s *ServerStore) ProcessWebhook(r *http.Request) (*InvoiceEvent, error)

type SpeedPolicy

type SpeedPolicy string

SpeedPolicy defines when an invoice is considered confirmed.

const (
	HighSpeed      SpeedPolicy = "HighSpeed"      // consider the invoice confirmed when the payment transaction has >= 0 confirmations (i.e. as soon as it is visible on the blockchain)
	MediumSpeed    SpeedPolicy = "MediumSpeed"    // consider the invoice confirmed when the payment transaction has >= 1 confirmation
	LowMediumSpeed SpeedPolicy = "LowMediumSpeed" // consider the invoice confirmed when the payment transaction has >= 2 confirmations
	LowSpeed       SpeedPolicy = "LowSpeed"       // consider the invoice confirmed when the payment transaction has >= 6 confirmations
)

type Store

type Store interface {
	CheckInvoiceAuth() error
	CreateInvoice(req *InvoiceRequest) (*Invoice, error)
	CreatePaymentRequest(req *PaymentRequestRequest) (*PaymentRequest, error)
	GetInvoice(id string) (*Invoice, error)
	GetPaymentRequest(id string) (*PaymentRequest, error)
	GetServerStatus() (*ServerStatus, error)
	InvoiceCheckoutLink(id string) string
	InvoiceCheckoutLinkPreferOnion(id string) string
	PaymentRequestLink(id string) string
	PaymentRequestLinkPreferOnion(id string) string
	ProcessWebhook(req *http.Request) (*InvoiceEvent, error)
}

type SyncStatus added in v0.3.0

type SyncStatus struct {
	CryptoCode      string `json:"cryptoCode"`
	ChainHeight     int    `json:"chainHeight"`
	SyncHeight      int    `json:"syncHeight"`
	NodeInformation struct {
		Headers              int     `json:"headers"`
		Blocks               int     `json:"blocks"`
		VerificationProgress float64 `json:"verificationProgress"`
	} `json:"nodeInformation"`
}

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL