Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Communication with SdI - sending invoice #28

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,10 @@

# ENV files
.env

# Ignore Certificate Signing Request files
*.csr
# Ignore private RSA key files
*.key
# Ignore p7m files
*.p7m
1 change: 1 addition & 0 deletions cmd/gobl.fatturapa/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func (o *rootOpts) cmd() *cobra.Command {

cmd.AddCommand(versionCmd())
cmd.AddCommand(convert(o).cmd())
cmd.AddCommand(transmit(o).cmd())

return cmd
}
Expand Down
126 changes: 126 additions & 0 deletions cmd/gobl.fatturapa/transmit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package main

import (
"fmt"
"io"
"os"
"path/filepath"

sdi "github.com/invopop/gobl.fatturapa/sdi"
"github.com/spf13/cobra"
)

type transmitOpts struct {
*rootOpts
config *sdi.Config
}

func transmit(o *rootOpts) *transmitOpts {
return &transmitOpts{rootOpts: o}
}

func (c *transmitOpts) cmd() *cobra.Command {
cmd := &cobra.Command{
Use: "transmit [file] [environment]",
Short: "Transmit a FatturaPA XML file to SdI in selected environment",
RunE: c.runE,
}

f := cmd.Flags()
f.Bool("verbose", false, "Logs all requests into the console")
f.String("ca-cert", "", "Path to a file containing the CA certificate")
f.String("cert", "", "Path to a file containing the SDI PEM certificate")
f.String("key", "", "Path to a file containing the sender PEM RSA private key")
f.String("env", "test", "Environment for running command")
_ = cmd.MarkFlagRequired("ca-cert")
_ = cmd.MarkFlagRequired("cert")
_ = cmd.MarkFlagRequired("key")

return cmd
}

func (c *transmitOpts) runE(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
verbose, err := cmd.Flags().GetBool("verbose")
if err != nil {
return err
}

config, err := getConfigByEnv(cmd)
if err != nil {
return err
}

caCertPool, err := loadDataFromFlag(cmd, "ca-cert")
if err != nil {
return err
}

certPEM, err := loadDataFromFlag(cmd, "cert")
if err != nil {
return err
}

keyPEM, err := loadDataFromFlag(cmd, "key")
if err != nil {
return err
}

client := sdi.NewClient(
sdi.WithDebugMode(verbose),
sdi.WithCACertPool(caCertPool),
sdi.WithClientCertPair(certPEM, keyPEM),
)

input, err := openInput(cmd, args)
if err != nil {
return err
}
defer input.Close() // nolint:errcheck

c.config = config

data, err := io.ReadAll(input)
if err != nil {
return fmt.Errorf("reading input: %w", err)
}
fileName := filepath.Base(args[0])

invOpts := sdi.InvoiceOpts{FileName: fileName, FileBody: data}

resp, err := sdi.SendInvoice(ctx, invOpts, client, *c.config)
if err != nil {
return fmt.Errorf("sending error: %w", err)
}

fmt.Printf("Invoice sent to SdI.\nHere is the response: %v\n", resp.Body.Response)

return nil
}

func getConfigByEnv(cmd *cobra.Command) (*sdi.Config, error) {
env, _ := cmd.Flags().GetString("env")
configs := map[string]*sdi.Config{
"dev": &sdi.DevelopmentSdIConfig,
"test": &sdi.TestSdIConfig,
"prod": &sdi.ProductionSdIConfig,
}
config, exists := configs[env]
if !exists {
return nil, fmt.Errorf("invalid environment: %s. Allowed values are 'dev', 'test', 'prod'", env)
}

return config, nil
}

func loadDataFromFlag(cmd *cobra.Command, flagName string) ([]byte, error) {
filePath, err := cmd.Flags().GetString(flagName)
if err != nil {
return nil, err
}
data, err := os.ReadFile(filePath)
if err != nil {
return nil, err
}
return data, nil
}
8 changes: 6 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ module github.com/invopop/gobl.fatturapa
go 1.20

require (
github.com/go-resty/resty/v2 v2.13.1
github.com/invopop/gobl v0.76.0
github.com/invopop/xmldsig v0.8.0
github.com/jarcoal/httpmock v1.3.1
github.com/magefile/mage v1.14.0
github.com/spf13/cobra v1.7.0
github.com/stretchr/testify v1.8.4
github.com/terminalstatic/go-xsd-validate v0.1.5
gitlab.com/flimzy/testy v0.12.4
)

Expand All @@ -31,8 +34,9 @@ require (
github.com/spf13/pflag v1.0.5 // indirect
github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693 // indirect
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.20.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
software.sslmate.com/src/go-pkcs12 v0.2.0 // indirect
)
56 changes: 50 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-resty/resty/v2 v2.13.1 h1:x+LHXBI2nMB1vqndymf26quycC4aggYJ7DECYbiz03g=
github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96ORAI6Q7d+0=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
Expand All @@ -31,6 +33,8 @@ github.com/invopop/xmldsig v0.8.0 h1:W/yRh/HcMSlZrkaVtIeycxmBLssXIfy437yNCvx4gD4
github.com/invopop/xmldsig v0.8.0/go.mod h1:dc3+2BYNw0vzauyZiOobTltp1t3BbvWSq7ae/F2gdk0=
github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso=
github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA=
github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww=
github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/labstack/echo/v4 v4.9.1 h1:GliPYSpzGKlyOhqIbG8nmHBo3i1saKWFOgh41AN3b+Y=
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
Expand All @@ -40,6 +44,7 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g=
github.com/otiai10/copy v1.10.0 h1:znyI7l134wNg/wDktoVQPxPkgvhDfGCYUasey+h0rDQ=
github.com/otiai10/copy v1.10.0/go.mod h1:rSaLseMUsZFFbsFGc7wCJnnkTAvdc5L6VWxPE4308Ww=
github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks=
Expand All @@ -63,32 +68,71 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/terminalstatic/go-xsd-validate v0.1.5 h1:RqpJnf6HGE2CB/lZB1A8BYguk8uRtcvYAPLCF15qguo=
github.com/terminalstatic/go-xsd-validate v0.1.5/go.mod h1:18lsvYFofBflqCrvo1umpABZ99+GneNTw2kEEc8UPJw=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
gitlab.com/flimzy/testy v0.12.4 h1:J2plNCG5d9FWfik30yOZrajcPrWbiDHrk0qw1nMstNU=
gitlab.com/flimzy/testy v0.12.4/go.mod h1:9wPR98kErJw1lrq/aIJ8UZ6A0Dn7CHU0T6Qx4b2FiyQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
72 changes: 72 additions & 0 deletions sdi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,78 @@

- [Production URI](https://fatturapa.it/)

## Manage the channel

1. Go to the
[Manage the channel](https://sdi.fatturapa.gov.it/SdI2FatturaPAWebSpa/GestireCanaleAction.do)
page.
2. Choose file to load the initial registration request.
The required file is `RichiestaAccreditamento.zip.p7m`.
Note the extension "zip.p7m" of the file.
3. Fill the "Security Code" field. This is a captcha.

After logging in, we have access to the following options:

- Interoperability Test
- View service agreement
- Change Endpoint

## Send an invoice

To send an invoice you need:
- invoice file in XML format
- file with CA certificates in PEM format
- PEM certificate (see the Certificato_Client folder)
- PEM RSA private key (generated during initial registration process)

Example of use:

```console
$ go run ./cmd/gobl.fatturapa transmit --ca-cert ./ca-all.pem --cert ./SDI-B85905495.pem --key ./key_client.key --verbose --env test invoice.xml
2024/05/28 17:00:00.000000 DEBUG RESTY
==============================================================================
~~~ REQUEST ~~~
POST /ricevi_file HTTP/1.1
HOST : testservizi.fatturapa.it
HEADERS:
Content-Type: text/plain; charset=utf-8
User-Agent: go-resty/2.13.1 (https://github.com/go-resty/resty)
BODY :
<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:typ='http://www.fatturapa.gov.it/sdi/ws/trasmissione/v1.0/types'><soapenv:Header/><soapenv:Body><typ:fileSdIAccoglienza><NomeFile>invoice.xml</NomeFile><File>FILE CONTENT</File></typ:fileSdIAccoglienza></soapenv:Body></soapenv:Envelope>
------------------------------------------------------------------------------
~~~ RESPONSE ~~~
STATUS : 200 OK
PROTO : HTTP/1.1
RECEIVED AT : 2024-05-28T17:00:00.500000000+02:00
TIME DURATION: 500.000000ms
HEADERS :
Cache-Control: no-cache="set-cookie, set-cookie2"
Content-Language: en-US
Content-Length: 716
Content-Type: multipart/related; boundary="MIMEBoundary_"; type="application/xop+xml"; start="<[email protected]>"; start-info="text/xml"
Date: Tue, 28 May 2024 15:00:00 GMT
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Set-Cookie: ==; HTTPOnly; Path=/; Domain=.fatturapa.it; HttpOnly
X-Powered-By: Servlet/3.0
BODY :
--MIMEBoundary_
Content-Type: application/xop+xml; charset=utf-8; type="text/xml"
Content-Transfer-Encoding: binary
Content-ID: <[email protected]>

<?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns2:rispostaSdIRiceviFile xmlns:ns2="http://www.fatturapa.gov.it/sdi/ws/trasmissione/v1.0/types"><IdentificativoSdI>29208092</IdentificativoSdI><DataOraRicezione>2024-05-28T17:00:00.200+02:00</DataOraRicezione></ns2:rispostaSdIRiceviFile></soapenv:Body></soapenv:Envelope>
--MIMEBoundary_--
==============================================================================
```

## Links

- [Manage the channel](https://sdi.fatturapa.gov.it/SdI2FatturaPAWebSpa/GestireCanaleAction.do)

## Pfx server certificate

```
$ openssl pkcs12 -export -certpbe PBE-SHA1-3DES -keypbe PBE-SHA1-3DES -nomac -out SDI-PIVA-SERVER.pfx -inkey key_server.key -in SDI-IT.INVOPOP.COM.pem -certfile ca-all.pem
Enter Export Password:
Verifying - Enter Export Password:
```
17 changes: 17 additions & 0 deletions sdi/cert/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

[Source link](https://www.fatturapa.gov.it/it/norme-e-regole/DocumentazioneSDI/)

These certificates can also be obtained with the following commands:

```console
$ openssl s_client -connect testservizi.fatturapa.it:443 -showcerts
$ openssl s_client -connect servizi.fatturapa.it:443 -showcerts
```

## Test Certificates

Contents of the `test` folder:
Expand Down Expand Up @@ -30,3 +37,13 @@ Contents of the `ca` folder:
for the production environment
- `UserTrustCA.cer`: CA certificate for servizi.fatturapa.it.cer
for the production environment

## Public keys

[Exchange System documentation](https://www.fatturapa.gov.it/en/norme-e-regole/DocumentazioneSDI/)

Public key of the client certificate of the SDICoop Transmission and SDICoop Reception Service.
Contents of the `keys` folder:

- `sdi_client_prod.cer_`: real flow
- `sdi_client_test.cer_`: test flow
Loading
Loading