README ¶
Amazon's Selling Partner API (SP-API) Golang SDK
Installation
go get -u github.com/alex-korobko/selling-partner-api-sdk
Progress
- authorization (authorization-api-model DOC)
- catalog (catalog-items-api-model DOC)
- fbaInbound (fulfillment-inbound-api-model DOC)
- fbaInventory (fba-inventory-api-model DOC)
- fbaOutbound (fulfillment-outbound-api-model DOC)
- feeds (feeds-api-model DOC)
- fees (product-fees-api-model DOC)
- finances (finances-api-model DOC)
- merchantFulfillment (merchant-fulfillment-api-model DOC)
- messaging (messaging-api-model DOC)
- notifications (notifications-api-model DOC)
- ordersV0 (orders-api-model DOC)
- productPricing (product-pricing-api-model DOC)
- reports (reports-api-model DOC)
- sales (sales-api-model DOC)
- sellers (sellers-api-model DOC)
- service (services-api-model DOC)
- shipping (shipping-api-model DOC)
- smallAndLight (fba-small-and-light-api DOC)
- solicitations (solicitations-api-model DOC)
- uploads (uploads-api-model DOC)
Example
package main
import (
"context"
"log"
"net/http"
"net/http/httputil"
sp "github.com/alex-korobko/selling-partner-api-sdk/pkg/selling-partner"
"github.com/alex-korobko/selling-partner-api-sdk/gosdk-models/amzn/selling-partner-api-go-sdk/sellers"
"github.com/google/uuid"
"github.com/pkg/errors"
)
func main() {
sellingPartner, err := sp.NewSellingPartner(&sp.Config{
ClientID: "<ClientID>",
ClientSecret: "<ClientSecret>",
RefreshToken: "<RefreshToken>",
AccessKeyID: "<AWS IAM User Access Key Id>",
SecretKey: "<AWS IAM User Secret Key>",
Region: "<AWS Region>",
RoleArn: "<AWS IAM Role ARN>",
})
if err != nil {
panic(err)
}
endpoint := "https://sellingpartnerapi-fe.amazon.com"
seller, err := sellers.NewClientWithResponses(endpoint,
sellers.WithRequestBefore(func(ctx context.Context, req *http.Request) error {
req.Header.Add("X-Amzn-Requestid", uuid.New().String()) //tracking requests
err = sellingPartner.SignRequest(req)
if err != nil {
return errors.Wrap(err, "sign error")
}
dump, err := httputil.DumpRequest(req, true)
if err != nil {
return errors.Wrap(err, "DumpRequest Error")
}
log.Printf("DumpRequest = %s", dump)
return nil
}),
sellers.WithResponseAfter(func(ctx context.Context, rsp *http.Response) error {
dump, err := httputil.DumpResponse(rsp, true)
if err != nil {
return errors.Wrap(err, "DumpResponse Error")
}
log.Printf("DumpResponse = %s", dump)
return nil
}),
)
if err != nil {
panic(err)
}
ctx := context.Background()
_, err = seller.GetMarketplaceParticipationsWithResponse(ctx)
if err != nil {
panic(err)
}
}
#Report Decryption
Amazon specification of version 2020-09-04
returns encrypted reports. To decrypt the reports you could use the Decrypt function of the decryption package.
Test example
The test example uses amzn.GetReportDocumentResponse
from Amazon models and the
Decrypt function to download, decrypt and dump report.
func TestSellingPartnerGetReportDocumentThirdParty(t *testing.T) {
sellingPartner, err := sp.NewSellingPartner(&sp.Config{
ClientID: "***",
ClientSecret: "***",
RefreshToken: "***",
AccessKeyID: "***",
SecretKey: "***",
Region: "***",
RoleArn: "***",
})
if err != nil {
t.Fatal("Failed to create NewSellingPartner: ", err)
}
report, err := reports.NewClientWithResponses(spiHost,
reports.WithRequestBefore(func(ctx context.Context, req *http.Request) error {
err = sellingPartner.SignRequest(req)
if err != nil {
return errors.Wrap(err, "sign error")
}
dump, err := httputil.DumpRequest(req, true)
if err != nil {
return errors.Wrap(err, "DumpRequest Error")
}
ioutil.WriteFile("test-samples/3dumpedThirdPartyReqGetReports.txt", dump, 0777)
return nil
}),
reports.WithResponseAfter(func(ctx context.Context, rsp *http.Response) error {
dump, err := httputil.DumpResponse(rsp, true)
if err != nil {
return errors.Wrap(err, "DumpResponse Error")
}
ioutil.WriteFile("test-samples/3dumpedThirdPartyRespGetReports.txt", dump, 0777)
return nil
}),
)
if err != nil {
t.Fatal("Failed to create NewClientWithResponses: ", err)
}
ctx := context.Background()
reportDocumentId := "***"
resp, err := report.GetReportDocument(ctx, reportDocumentId)
if err != nil {
t.Fatal("Failed to make GetReportDocument request: ", err)
}
if resp.StatusCode < 200 || resp.StatusCode > 299 {
t.Fatal("Service returned a status that isn't 2xx: ", resp.StatusCode)
}
defer resp.Body.Close()
var bodyData []byte
resp.Body.Read(bodyData)
content, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatal("Failed to read GetReportDocument response body: ", err)
}
var reportDocumentResp amzn.GetReportDocumentResponse
err = json.Unmarshal(content, &reportDocumentResp)
if err != nil {
t.Fatal("Failed to unmarshall GetReportDocument response: ", err)
}
if reportDocumentResp.Errors != nil {
t.Fatal("Got errors in the GetReportDocument response: ", reportDocumentResp.Errors)
}
respWithDocContent, err := http.Get(reportDocumentResp.Payload.Url)
if err != nil {
t.Fatal("failed to make request to "+reportDocumentResp.Payload.Url+" : ", err)
}
if respWithDocContent.StatusCode < 200 || respWithDocContent.StatusCode > 299 {
t.Fatal("Service returned a status that isn't 2xx: ", respWithDocContent.StatusCode)
}
defer respWithDocContent.Body.Close()
reportContentBytes, err := ioutil.ReadAll(respWithDocContent.Body)
if err != nil {
t.Fatal("Failed to read Report content body: ", err)
}
ioutil.WriteFile("test-samples/3_encrypted_"+reportDocumentId+"_"+reportType+"_report.txt", reportContentBytes, 0777)
decryptedFilecontent, err := decryption.Decrypt(reportDocumentResp.Payload.EncryptionDetails.Key, reportDocumentResp.Payload.EncryptionDetails.InitializationVector, reportContentBytes)
if err != nil {
t.Fatal("Failed to decrypt file content: ", err)
}
ioutil.WriteFile("test-samples/3_"+reportDocumentId+"_"+reportType+"_report.txt", decryptedFilecontent, 0777)
}
Click to show internal directories.
Click to hide internal directories.