App Store Server Notifications in Golang

İzni Burak Demirtaş
Jotform Tech
Published in
3 min readOct 10, 2023

--

I’ve been working on App Store Server Notifications, because we need In-App-Subscription feature in order to offer our subscription models to our users on our mobile apps.

For those, who have never heard of App Store Server Notifications, I’ll try to explain what they are.

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.

To use this service, we’ve created a new endpoint and defined it to the “App Information” page of the related app on App Store Connect. So, Apple will be able to send notification about the subscriptions via our webhook URL and we’ll save and track them, taking action (like upgrade or downgrade users) as needed.

That’s the summary of the flow of the implementation. After that, Apple send the request to our server with a JSON data string like this:

{"signedPayload": "eyJhbGciOiJFUzI1NiIsIng1YyI6WyJNSUlFTURDQ0E3YWdBd0lCQWdJUWFQb1BsZHZwU29FSDBsQnJqRFB2OWpBS0JnZ3Foa......"}

The data (signedPayload) signed by the App Store and contains all data we need, including transactionInfo and renewalInfo of the App Store Subscriptions or Purchases. signedPayload ’s value is a kind of JWS and has three parts separated by . char. These parts are:

  • Header (has two parts: algorithm and type of the token)
  • Payload (the data about the purchases like transaction or renewal)
  • Signature

App Store Server Notifications uses anES256 algorithm and x5c (X.509 Certificate Chain) while signing the payload they sent. These are important details, because we’ll use these algorithms and certificate while parsing and verifying to payload.

Building a new package

For all these process, I’ve prepared a package called appstore-notifications-go in order to handle these processes in Golang. You can verify and parse the signedPayload data and access the payload data quickly by using this package.

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

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

Then, you can start to use the package with the signedPayload and Apple Root CA — G3 Root certificate. You need to download the certificate and create a .pem file by using the certificate you downloaded. To create the .pem file, you can use the following command:

openssl x509 -in AppleRootCA-G3.cer -out cert.pem

After that, you can start the implementation:

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)
}

That’s all. Now, You can access the all data in the payload by using one of the four 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.

In summary, you can verify, parse and access the data of App Store Server Notification quick and simple by using the appstore-notifications-go package.

Please feel free to flag any bugs you find or suggest improvements. I would be happy to hear them :) We can make it better together. You can check the package on GitHub.

If you want contact to me, you can check my X profile or my personal page.

See you for my next posts about Golang!

--

--

nam-ı diğer Buki. 👨🏻‍💻 Sr. Software Engineer @Jotform — #php #golang #javascript #reactnative — Co-Founder at HaberSistemim & MemleketApp