Documentation ¶
Index ¶
- Constants
- Variables
- func IsNetworkError(err error) bool
- func IsSuccess(code int64) bool
- func LoadCert(path, password string) (*rsa.PrivateKey, *x509.Certificate, error)
- func LoadCertChain(certPath string, certPassword string) (*rsa.PrivateKey, *x509.Certificate, []*x509.Certificate, error)
- func NetAmount(taxCode int64, price float64) float64
- func ParseErrorCode(code int64) string
- func ReceiptBytes(privateKey *rsa.PrivateKey, params ReceiptParams, customer Customer, ...) ([]byte, error)
- func ReceiptLink(e env.Env, receiptCode string, gc int64, receiptTime string) string
- func ReportBytes(privateKey *rsa.PrivateKey, params *ReportParams, address Address, ...) ([]byte, error)
- func ReportTaxRateID(taxCode int64) string
- func RequestURL(e env.Env, action Action) string
- func Sign(privateKey *rsa.PrivateKey, payload []byte) ([]byte, error)
- func SignPayload(privateKey *rsa.PrivateKey, payload []byte) ([]byte, error)
- func ValueAddedTaxAmount(taxCode int64, price float64) float64
- func ValueAddedTaxID(taxCode int64) string
- func ValueAddedTaxRate(taxCode int64) float64
- func VerifySignature(publicKey *rsa.PublicKey, payload []byte, signature string) error
- type Action
- type Address
- type CertLoader
- type Client
- func (c *Client) FetchToken(ctx context.Context, url string, request *TokenRequest) (*TokenResponse, error)
- func (c *Client) FetchTokenWithMw(ctx context.Context, url string, request *TokenRequest, ...) (*TokenResponse, error)
- func (c *Client) Register(ctx context.Context, url string, privateKey *rsa.PrivateKey, ...) (*RegistrationResponse, error)
- func (c *Client) SetHttpClient(http *http.Client)
- func (c *Client) SubmitReceipt(ctx context.Context, url string, headers *RequestHeaders, ...) (*Response, error)
- func (c *Client) SubmitReport(ctx context.Context, url string, headers *RequestHeaders, ...) (*Response, error)
- type Customer
- type CustomerID
- type Error
- type FetchTokenFunc
- type Item
- type ItemProcessResponse
- type NetworkError
- type OnTokenResponse
- type Option
- type PayloadSigner
- type Payment
- type PaymentType
- type RawRequest
- type ReceiptParams
- type ReceiptRequest
- type RegistrationRequest
- type RegistrationResponse
- type ReportParams
- type ReportRequest
- type ReportTotals
- type RequestHeaders
- type Response
- func SubmitRawRequest(ctx context.Context, headers *RequestHeaders, raw *RawRequest) (*Response, error)
- func SubmitReceipt(ctx context.Context, requestURL string, headers *RequestHeaders, ...) (*Response, error)
- func SubmitReport(ctx context.Context, url string, headers *RequestHeaders, ...) (*Response, error)
- type Service
- type SignatureVerifier
- type TAXCODES
- type TokenRequest
- type TokenResponse
- type TokenResponseMiddleware
- type URL
- type VATTOTAL
- type ValueAddedTax
Constants ¶
const ( SuccessCode int64 = 0 InvalidSignatureCode int64 = 1 InvalidTaxID int64 = 3 ApprovalRequired int64 = 4 UnhandledException int64 = 5 InvalidSerial int64 = 6 InvalidClientHeader int64 = 7 InvalidCertificate int64 = 8 )
const ( StandardVATID = "A" StandardVATRATE = 18.00 StandardVATCODE = 1 SpecialVATID = "B" SpecialVATRATE = 0.00 SpecialVATCODE = 2 ZeroVATID = "C" ZeroVATRATE = 0.00 ZeroVATCODE = 3 SpecialReliefVATID = "D" SpecialReliefVATRATE = 0.00 SpecialReliefVATCODE = 4 ExemptedVATID = "E" ExemptedVATRATE = 0.00 ExemptedVATCODE = 5 TaxableItemCode = 1 TaxableItemId = "A" NonTaxableItemCode = 3 NonTaxableItemId = "C" )
const ( RegisterProductionURL = "https://vfd.tra.go.tz/api/vfdRegReq" FetchTokenProductionURL = "https://vfd.tra.go.tz/vfdtoken" //nolint:gosec SubmitReceiptProductionURL = "https://vfd.tra.go.tz/api/efdmsRctInfo" SubmitReportProductionURL = "https://vfd.tra.go.tz/api/efdmszreport" VerifyReceiptProductionURL = "https://verify.tra.go.tz/" RegisterTestingURL = "https://virtual.tra.go.tz/efdmsRctApi/api/vfdRegReq" FetchTokenTestingURL = "https://virtual.tra.go.tz/efdmsRctApi/vfdtoken" //nolint:gosec SubmitReceiptTestingURL = "https://virtual.tra.go.tz/efdmsRctApi/api/efdmsRctInfo" SubmitReportTestingURL = "https://virtual.tra.go.tz/efdmsRctApi/api/efdmszreport" VerifyReceiptTestingURL = "https://virtual.tra.go.tz/efdmsRctVerify/" RegisterClientAction Action = "register" FetchTokenAction Action = "token" SubmitReceiptAction Action = "receipt" SubmitReportAction Action = "report" ReceiptVerificationAction Action = "verification" CashPaymentType PaymentType = "CASH" CreditCardPaymentType PaymentType = "CCARD" ChequePaymentType PaymentType = "CHEQUE" InvoicePaymentType PaymentType = "INVOICE" ElectronicPaymentType PaymentType = "EMONEY" TINCustomerID CustomerID = 1 LicenceCustomerID CustomerID = 2 VoterIDCustomerID CustomerID = 3 PassportCustomerID CustomerID = 4 NIDACustomerID CustomerID = 5 NonCustomerID CustomerID = 6 MeterNumberCustomerID CustomerID = 7 SubmitReceiptRoutingKey string = "vfdrct" SubmitReportRoutingKey string = "vfdzreport" ContentTypeXML string = "application/xml" RegistrationRequestClient string = "webapi" )
Variables ¶
var ErrFetchToken = errors.New("fetch token failed")
ErrFetchToken is the error returned when the token request fails. It is a wrapper for the underlying error.
var ErrReceiptUploadFailed = errors.New("receipt upload failed")
var ErrRegistrationFailed = errors.New("registration failed")
var ErrReportSubmitFailed = fmt.Errorf("report submit failed")
Functions ¶
func IsNetworkError ¶
IsNetworkError returns true if the error is a NetworkError.
func IsSuccess ¶
IsSuccess checks the response ack code and return true if the code means success and false if otherwise
func LoadCert ¶
func LoadCert(path, password string) (*rsa.PrivateKey, *x509.Certificate, error)
func LoadCertChain ¶
func LoadCertChain(certPath string, certPassword string) (*rsa.PrivateKey, *x509.Certificate, []*x509.Certificate, error)
func NetAmount ¶
NetAmount calculates the net price of a product of a certain ValueAddedTax category. This is the NetAmount which is collected by the seller without the ValueAddedTax. The buyer is charged this NetAmount plus the ValueAddedTax NetAmount. After calculating the answer is rounded to 2 decimal places. price = netPrice + netPrice * (vatRate / 100)
func ParseErrorCode ¶
ParseErrorCode parses the error code and returns the corresponding error message.
func ReceiptBytes ¶
func ReceiptBytes(privateKey *rsa.PrivateKey, params ReceiptParams, customer Customer, items []Item, payments []Payment, ) ([]byte, error)
func ReceiptLink ¶
ReceiptLink creates a link to the receipt it accepts RECEIPTCODE, GC and the RECEIPTTIME and env.Env to know if the receipt was created during testing or production.
func ReportBytes ¶
func ReportBytes(privateKey *rsa.PrivateKey, params *ReportParams, address Address, vats []VATTOTAL, payments []Payment, totals ReportTotals, ) ([]byte, error)
ReportBytes returns the bytes of the report payload. It calls xml.Marshal on the report. then replace all the occurrences of <PAYMENT>, </PAYMENT>, <VATTOTAL>, </VATTOTAL> with empty string "" and then add the xml.Header to the beginning of the payload.
func ReportTaxRateID ¶
ReportTaxRateID creates a string that contains the ValueAddedTax rate and the ValueAddedTax id of a certain ValueAddedTax category. It returns "A-18.00" for standard ValueAddedTax, "B-10.00" for special ValueAddedTax, "C-0.00" for zero ValueAddedTax and so on. The ID is then used in Z Report to indicate the ValueAddedTax rate and the ValueAddedTax id.
func RequestURL ¶
RequestURL returns the URL for the specified Action and specified env.Env returns empty string if either action or env is not recognized
func SignPayload ¶
func SignPayload(privateKey *rsa.PrivateKey, payload []byte) ([]byte, error)
func ValueAddedTaxAmount ¶
ValueAddedTaxAmount calculates the amount of ValueAddedTax that is charged to the buyer. The answer is rounded to 2 decimal places.
func ValueAddedTaxID ¶
ValueAddedTaxID returns the ValueAddedTax id of a certain ValueAddedTax category It returns "A" for standard ValueAddedTax, "B" for special ValueAddedTax, "C" for zero ValueAddedTax,"D" for special relief and "E" for exempted ValueAddedTax.
func ValueAddedTaxRate ¶
ValueAddedTaxRate returns the ValueAddedTax rate of a certain ValueAddedTax category
Types ¶
type Action ¶
type Action string
Action signifies the action to be performed among the four defined actions which are INSTANCE registration, token fetching, submission of receipt and submission of report.
type CertLoader ¶
type CertLoader func(certPath string, certPassword string) (*rsa.PrivateKey, *x509.Certificate, error)
CertLoader loads a certificate from a file and returns the private key and the certificate
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
func (*Client) FetchToken ¶
func (c *Client) FetchToken(ctx context.Context, url string, request *TokenRequest, ) (*TokenResponse, error)
func (*Client) FetchTokenWithMw ¶
func (c *Client) FetchTokenWithMw(ctx context.Context, url string, request *TokenRequest, callback OnTokenResponse, ) (*TokenResponse, error)
func (*Client) Register ¶
func (c *Client) Register(ctx context.Context, url string, privateKey *rsa.PrivateKey, request *RegistrationRequest, ) (*RegistrationResponse, error)
func (*Client) SetHttpClient ¶
SetHttpClient sets the http client
func (*Client) SubmitReceipt ¶
func (c *Client) SubmitReceipt( ctx context.Context, url string, headers *RequestHeaders, privateKey *rsa.PrivateKey, receipt *ReceiptRequest, ) (*Response, error)
func (*Client) SubmitReport ¶
func (c *Client) SubmitReport( ctx context.Context, url string, headers *RequestHeaders, privateKey *rsa.PrivateKey, report *ReportRequest, ) (*Response, error)
type Customer ¶
type Customer struct { Type CustomerID ID string Name string Mobile string }
Customer contains customer information
type CustomerID ¶
type CustomerID int
CustomerID is the type of ID the customer used during purchase The Type of ID is to be included in the receipt. Allowed values for CustomerID are 1 through 7. The number to type mapping are as follows: 1: Tax Identification Number (TIN), 2: Driving License, 3: Voters Number, 4: Travel Passport, 5: National ID, 6: NIL (No Identity Used), 7: Meter Number
type FetchTokenFunc ¶
type FetchTokenFunc func(ctx context.Context, url string, request *TokenRequest) (*TokenResponse, error)
FetchTokenFunc is a function that fetches a token from the VFD server.
type Item ¶
type Item struct { ID string Description string TaxCode int64 Quantity float64 UnitPrice float64 Discount float64 }
Item represent a purchased item. TaxCode is an integer that can take the value of 1 for taxable items and 3 for non-taxable items. Discount is for the whole package not a unit discount
type ItemProcessResponse ¶
type ItemProcessResponse struct { ITEMS []*models.ITEM VATTOTALS []*models.VATTOTAL TOTALS models.TOTALS }
func ProcessItems ¶
func ProcessItems(items []Item) *ItemProcessResponse
ProcessItems processes the []Items in the submitted receipt request and create []*models.ITEM which is used to create the xml request also calculates the total discount, total tax exclusive and total tax inclusive
type NetworkError ¶
NetworkError is returned when there is an error in the network.
func (*NetworkError) Error ¶
func (e *NetworkError) Error() string
func (*NetworkError) Unwrap ¶
func (e *NetworkError) Unwrap() error
Unwrap returns the underlying error.
type OnTokenResponse ¶
type OnTokenResponse func(context.Context, *TokenResponse) error
OnTokenResponse is a callback function that is called when a token is received.
func WrapTokenResponseMiddleware ¶
func WrapTokenResponseMiddleware(next OnTokenResponse, middlewares ...TokenResponseMiddleware) OnTokenResponse
WrapTokenResponseMiddleware wraps a TokenResponseMiddleware with a OnTokenResponse.
type PayloadSigner ¶
type PayloadSigner func(privateKey *rsa.PrivateKey, payload []byte) ([]byte, error)
PayloadSigner signs a payload using the private key of the signing certificate all requests to the VFD API must be signed.
type Payment ¶
type Payment struct { Type PaymentType Amount float64 }
type PaymentType ¶
type PaymentType string
PaymentType represent the type of payment that is recognized by the VFD server There are five types of payments: CASH, CHEQUE, CCARD, EMONEY and INVOICE.
type RawRequest ¶
RawRequest contains information needed to send receipt/z report file to the vfd server.
type ReceiptParams ¶
type ReceiptParams struct { Date string Time string TIN string RegistrationID string EFDSerial string ReceiptNum string DailyCounter int64 GlobalCounter int64 ZNum string ReceiptVNum string }
ReceiptParams contains parameters icluded while sending the receipts
type ReceiptRequest ¶
type ReceiptRequest struct { Params ReceiptParams Customer Customer Items []Item Payments []Payment }
type RegistrationRequest ¶
type RegistrationResponse ¶
type RegistrationResponse struct { ACKCODE string `xml:"ACKCODE"` ACKMSG string `xml:"ACKMSG"` REGID string `xml:"REGID"` SERIAL string `xml:"SERIAL"` UIN string `xml:"UIN"` TIN string `xml:"TIN"` VRN string `xml:"VRN"` MOBILE string `xml:"MOBILE"` ADDRESS string `xml:"ADDRESS"` STREET string `xml:"STREET"` CITY string `xml:"CITY"` COUNTRY string `xml:"COUNTRY"` NAME string `xml:"NAME"` RECEIPTCODE string `xml:"RECEIPTCODE"` REGION string `xml:"REGION"` ROUTINGKEY string `xml:"ROUTINGKEY"` GC int64 `xml:"GC"` TAXOFFICE string `xml:"TAXOFFICE"` USERNAME string `xml:"USERNAME"` PASSWORD string `xml:"PASSWORD"` TOKENPATH string `xml:"TOKENPATH"` TAXCODES TAXCODES `xml:"TAXCODES"` }
func Register ¶
func Register(ctx context.Context, requestURL string, privateKey *rsa.PrivateKey, request *RegistrationRequest, ) (*RegistrationResponse, error)
Register send the registration for a Virtual Fiscal Device to the VFD server. The registration request is signed with the private key of the certificate used to authenticate the INSTANCE.
type ReportParams ¶
type ReportRequest ¶
type ReportRequest struct { Params *ReportParams Address *Address Totals *ReportTotals VATS []VATTOTAL Payment []Payment }
type ReportTotals ¶
type ReportTotals struct { DailyTotalAmount float64 Gross float64 Corrections float64 Discounts float64 Surcharges float64 TicketsVoid int64 TicketsVoidTotal float64 TicketsFiscal int64 TicketsNonFiscal int64 }
ReportTotals contains different number of totals
type RequestHeaders ¶
RequestHeaders represent collection of request headers during receipt or Z report sending via VFD Service.
type Response ¶
type Response struct { Number int64 `json:"number,omitempty"` Date string `json:"date,omitempty"` Time string `json:"time,omitempty"` Code int64 `json:"code,omitempty"` Message string `json:"message,omitempty"` }
Response contains details returned when submitting a receipt to the VFD Service or a Z report. Number (int) is the receipt number in case of a receipt submission and the Z report number in case of a Z report submission. Date (string) is the date of the receipt or Z report submission. The format is YYYY-MM-DD. Time (string) is the time of the receipt or Z report submission. The format is HH24:MI:SS Code (int) is the response code. 0 means success. Message (string) is the response message.
func SubmitRawRequest ¶
func SubmitRawRequest(ctx context.Context, headers *RequestHeaders, raw *RawRequest) (*Response, error)
SubmitRawRequest is useful for submitting requests that are in form of XML files content of the file is read and submitted to the server as is.
func SubmitReceipt ¶
func SubmitReceipt(ctx context.Context, requestURL string, headers *RequestHeaders, privateKey *rsa.PrivateKey, receiptRequest *ReceiptRequest, ) (*Response, error)
SubmitReceipt uploads a receipt to the VFD server.
func SubmitReport ¶
func SubmitReport(ctx context.Context, url string, headers *RequestHeaders, privateKey *rsa.PrivateKey, report *ReportRequest, ) (*Response, error)
type Service ¶
type Service interface { // Register is used to register a virtual fiscal device (VFD) with the VFD Service. // If successful, the VFD Service returns a registration response containing the // VFD details and the credentials to use when submitting receipts and Z reports. // Registering a VFD is a one-time operation. The subsequent calls to Register will // yield the same response.VFD should store the registration response to // avoid calling Register again. Register(ctx context.Context, url string, privateKey *rsa.PrivateKey, request *RegistrationRequest, ) (*RegistrationResponse, error) // FetchToken is used to fetch a token from the VFD Service. The token is used // to authenticate the VFD when submitting receipts and Z reports. // credentials used here are the ones returned by the Register method. FetchToken(ctx context.Context, url string, request *TokenRequest) (*TokenResponse, error) // SubmitReceipt is used to submit a receipt to the VFD Service. The receipt // is signed using the private key. The private key is obtained from the certificate // issued by the Revenue Authority during integration. SubmitReceipt( ctx context.Context, url string, headers *RequestHeaders, privateKey *rsa.PrivateKey, receipt *ReceiptRequest) (*Response, error) // SubmitReport is used to submit a Z report to the VFD Service. The Z report // is signed using the private key. The private key is obtained from the certificate // issued by the Revenue Authority during integration. SubmitReport( ctx context.Context, url string, headers *RequestHeaders, privateKey *rsa.PrivateKey, report *ReportRequest) (*Response, error) }
type SignatureVerifier ¶
SignatureVerifier verifies the signature of a payload using the public key of the signing certificate
type TokenRequest ¶
TokenRequest contains the request parameters needed to get a token. GrantType - The type of the grant_type. Username - The username of the user. Password - The password of the user.
type TokenResponse ¶
type TokenResponse struct { Code string `json:"code,omitempty"` Message string `json:"message,omitempty"` AccessToken string `json:"access_token,omitempty"` TokenType string `json:"token_type,omitempty"` ExpiresIn int64 `json:"expires_in,omitempty"` Error string `json:"error,omitempty"` }
TokenResponse contains the response parameters returned by the token endpoint.
func FetchToken ¶
func FetchToken(ctx context.Context, url string, request *TokenRequest) (*TokenResponse, error)
FetchToken retrieves a token from the VFD server. If the status code is not 200, an error is returned. Error Message will contain TokenResponse.Code and TokenResponse.Message FetchToken wraps internally a *http.Client responsible for making http calls. It has a timeout of 70 seconds. It is advised to call this only when the previous token has expired. It will still work if called before the token expires.
func FetchTokenWithMw ¶
func FetchTokenWithMw(ctx context.Context, url string, request *TokenRequest, callback OnTokenResponse) (*TokenResponse, error)
FetchTokenWithMw retrieves a token from the VFD server then passes it to the callback function This is beacuse the response might have a code and message that needs to be handled.
func (*TokenResponse) String ¶
func (tr *TokenResponse) String() string
type TokenResponseMiddleware ¶
type TokenResponseMiddleware func(next OnTokenResponse) OnTokenResponse
TokenResponseMiddleware is a middleware function that is called when a token is received.
type URL ¶
type URL struct { Registration string FetchToken string SubmitReceipt string SubmitReport string VerifyReceipt string }
URL is a struct that holds the URLs for the four actions
type ValueAddedTax ¶
type ValueAddedTax struct { ID string // ID is a character that identifies the ValueAddedTax it can be A,B,C,D or E Code int64 // Code is a number that identifies the ValueAddedTax it can be 0,1,2,3 or 4 Name string Percentage float64 }
func ParseTaxCode ¶
func ParseTaxCode(code int64) ValueAddedTax
func (*ValueAddedTax) Amount ¶
func (v *ValueAddedTax) Amount(totalAmount float64) float64
Amount calculates the amount of ValueAddedTax that is charged to the buyer. The answer is rounded to 2 decimal places.
func (*ValueAddedTax) NetAmount ¶
func (v *ValueAddedTax) NetAmount(totalAmount float64) float64