v2

package module
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Apr 26, 2024 License: MIT Imports: 7 Imported by: 0

README

App Store Server Notifications in Golang PkgGoDev

appstore-notifications-go is a Golang package designed to assist in handling, verifying, and parsing the App Store Server Notifications, which is a webhook service corresponds to Apple's App Store events related to your apps.

App Store Server Notifications is a service provided by Apple for its App Store. It's designed to notify developers about key events and changes related to their app's in-app purchases and subscriptions. By integrating this service into their server-side logic, developers can receive real-time (I think, almost real-time) updates about various events without having to repeatedly poll the Apple servers.

Install

To install the package, you can use following command on your terminal in your project directory:

go get github.com/izniburak/appstore-notifications-go

Examples

package main

import (
	"encoding/json"
	"fmt"
	"strings"
	appstore "github.com/izniburak/appstore-notifications-go"
)

func main() {
	// App Store Server Notification Request JSON String
	appStoreServerRequest := "..." // {"signedPayload":"..."}
	var request appstore.AppStoreServerRequest
	err := json.Unmarshal([]byte(appStoreServerRequest), &request) // bind byte to header structure
	if err != nil {
		panic(err)
	}

	// Apple Root CA - G3 Root certificate
	// for details: https://www.apple.com/certificateauthority/
	// you need download it and covert it to a valid pem file in order to verify X5c certificates
	// `openssl x509 -in AppleRootCA-G3.cer -out cert.pem`
	rootCert := "-----BEGIN CERTIFICATE----- ......"
	if rootCert == "" {
		panic("Apple Root Cert not valid")
	}

	appStoreServerNotification := appstore.New(request.SignedPayload, rootCert)
	fmt.Printf("App Store Server Notification is valid?: %t\n", appStoreServerNotification.IsValid)
	fmt.Printf("Product Id: %s\n", appStoreServerNotification.TransactionInfo.ProductId)
}

You can access the all data in the payload by using one of the 4 params in instance of the AppStoreServerNotification:

  • instance.Payload: Access the Payload.
  • instance.TransactionInfo: Access the Transaction Info.
  • instance.RenewalInfo: Access the Renewal Info.
  • instance.IsValid: Check the payload parsed and verified successfully.

Contributing

  1. Fork this repo
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors

  • izniburak İzni Burak Demirtaş - creator, maintainer

License

The MIT License (MIT) - see license.md for more details

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AppStoreServerNotification

type AppStoreServerNotification struct {
	Payload         *NotificationPayload
	TransactionInfo *TransactionInfo
	RenewalInfo     *RenewalInfo
	IsValid         bool
	IsTest          bool
	// contains filtered or unexported fields
}

func New

func New(payload string, appleRootCert string) *AppStoreServerNotification

type AppStoreServerRequest

type AppStoreServerRequest struct {
	SignedPayload string `json:"signedPayload"`
}

type ExternalPurchaseToken added in v1.2.0

type ExternalPurchaseToken struct {
	ExternalPurchaseId string `json:"externalPurchaseId"`
	TokenCreationDate  int    `json:"tokenCreationDate"`
	AppAppleId         string `json:"appAppleId"`
	BundleId           string `json:"bundleId"`
}

type NotificationData

type NotificationData struct {
	AppAppleId               int    `json:"appAppleId"`
	BundleId                 string `json:"bundleId"`
	BundleVersion            string `json:"bundleVersion"`
	Environment              string `json:"environment"`
	SignedRenewalInfo        string `json:"signedRenewalInfo"`
	SignedTransactionInfo    string `json:"signedTransactionInfo"`
	Status                   int32  `json:"status"`
	ConsumptionRequestReason string `json:"consumptionRequestReason,omitempty"`
}

type NotificationHeader

type NotificationHeader struct {
	Alg string   `json:"alg"`
	X5c []string `json:"x5c"`
}

type NotificationPayload

type NotificationPayload struct {
	jwt.StandardClaims
	NotificationType      string                `json:"notificationType"`
	Subtype               string                `json:"subtype"`
	NotificationUUID      string                `json:"notificationUUID"`
	Version               string                `json:"version"`
	SignedDate            int                   `json:"signedDate"`
	Summary               NotificationSummary   `json:"summary,omitempty"`
	Data                  NotificationData      `json:"data,omitempty"`
	ExternalPurchaseToken ExternalPurchaseToken `json:"externalPurchaseToken,omitempty"`
}

type NotificationSummary

type NotificationSummary struct {
	RequestIdentifier      string   `json:"requestIdentifier"`
	AppAppleId             string   `json:"appAppleId"`
	BundleId               string   `json:"bundleId"`
	ProductId              string   `json:"productId"`
	Environment            string   `json:"environment"`
	StoreFrontCountryCodes []string `json:"storefrontCountryCodes"`
	FailedCount            int64    `json:"failedCount"`
	SucceededCount         int64    `json:"succeededCount"`
}

type RenewalInfo

type RenewalInfo struct {
	jwt.StandardClaims
	AutoRenewProductId          string `json:"autoRenewProductId"`
	AutoRenewStatus             int32  `json:"autoRenewStatus"`
	Environment                 string `json:"environment"`
	ExpirationIntent            int32  `json:"expirationIntent"`
	GracePeriodExpiresDate      int    `json:"gracePeriodExpiresDate"`
	IsInBillingRetryPeriod      bool   `json:"isInBillingRetryPeriod"`
	OfferIdentifier             string `json:"offerIdentifier"`
	OfferType                   int32  `json:"offerType"`
	OriginalTransactionId       string `json:"originalTransactionId"`
	PriceIncreaseStatus         int32  `json:"priceIncreaseStatus"`
	ProductId                   string `json:"productId"`
	RecentSubscriptionStartDate int    `json:"recentSubscriptionStartDate"`
	RenewalDate                 int    `json:"renewalDate"`
	SignedDate                  int    `json:"signedDate"`
}

type TransactionInfo

type TransactionInfo struct {
	jwt.StandardClaims
	AppAccountToken             string `json:"appAccountToken"`
	BundleId                    string `json:"bundleId"`
	Currency                    string `json:"currency,omitempty"`
	Environment                 string `json:"environment"`
	ExpiresDate                 int    `json:"expiresDate"`
	InAppOwnershipType          string `json:"inAppOwnershipType"`
	IsUpgraded                  bool   `json:"isUpgraded"`
	OfferDiscountType           string `json:"offerDiscountType"`
	OfferIdentifier             string `json:"offerIdentifier"`
	OfferType                   int32  `json:"offerType"`
	OriginalPurchaseDate        int    `json:"originalPurchaseDate"`
	OriginalTransactionId       string `json:"originalTransactionId"`
	Price                       int64  `json:"price,omitempty"`
	ProductId                   string `json:"productId"`
	PurchaseDate                int    `json:"purchaseDate"`
	Quantity                    int32  `json:"quantity"`
	RevocationDate              int    `json:"revocationDate"`
	RevocationReason            int32  `json:"revocationReason"`
	SignedDate                  int    `json:"signedDate"`
	StoreFront                  string `json:"storefront"`
	StoreFrontId                string `json:"storefrontId"`
	SubscriptionGroupIdentifier string `json:"subscriptionGroupIdentifier"`
	TransactionId               string `json:"transactionId"`
	TransactionReason           string `json:"transactionReason"`
	Type                        string `json:"type"`
	WebOrderLineItemId          string `json:"webOrderLineItemId"`
}

Jump to

Keyboard shortcuts

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