go-iap

module
v0.3.4 Latest Latest
Warning

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

Go to latest
Published: May 27, 2022 License: MIT

README

go-iap

Build Status codecov.io

go-iap verifies the purchase receipt via AppStore or GooglePlayStore.

Current API Documents:

  • AppStore: GoDoc
  • GooglePlay: GoDoc

Differences from original

This repository is forked from dogenzaka/go-iap

  • supports iOS6 Style receipt
  • some api for iap receipts

Dependencies

go get github.com/parnurzeal/gorequest
go get golang.org/x/net/context
go get golang.org/x/oauth2
go get google.golang.org/api/androidpublisher/v2

Installation

go get github.com/evalphobia/go-iap/appstore
go get github.com/evalphobia/go-iap/playstore

Quick Start

In App Purchase (via App Store)
import(
	"log"

	"github.com/evalphobia/go-iap/appstore"
)

func buy() {
	client := appstore.NewWithConfig(appstore.Config{
		TimeOut:      30 * time.Second,
		IsProduction: true,
		Retry:        true,  // retry when HTTP error status
		Debug:        false, // show HTTP request
	})

	// call apple store api to check receipt
	resp, err := client.Verify(appstore.IAPRequest{
		ReceiptData: `<your receipt data encoded by base64>`,
		Password:    `<your app's shared secret (a hexadecimal string).>`,
	})
	switch {
	case err != nil:
		log.Errof("error occured on api call: %s", err.Error())
		return
	case !resp.IsValidReceipt():
		log.Errof("invalid receipt status: %d", resp.Status)
		return
	case resp.BundleID != "<my app bundle id>":
		log.Errof("invalid bundle id: %s", resp.BundleID)
	}

	// check new receipt or not
	productID := `<prodct id>`
	transactionIDs := resp.GetTransactionIDsByProduct(productID)
	transactionIDs = filterNeverUsedTransactionIDs(transactionIDs) // check if already used one or not by your own logic
	if len(transactionIDs) == 0 {
		log.Errof("all of trnasaction id already used")
		return
	}

	var inApp *appstore.ReceiptInApp
	switch {
	case resp.IsAutoRenewable():
		// for auto-renew: last expires
		inApp = resp.GetLastExpiresByProductID(productID)
	default:
		// for consume: first element
		inApp = resp.GetByTransactionID(transactionIDs[0])
	}

	// unknown error
	if inApp == nil {
		log.Errof("cannot find valid in_app data by unknown error")
		return
	}

	// save iap data of valid receipt...
}
In App Billing (via GooglePlay)
import(
	"log"

	"golang.org/x/oauth2"
	"github.com/evalphobia/go-iap/playstore"
)

// check receipt
func buy() {
	// You need to prepare a public key for your Android app's in app billing
	// at https://console.developers.google.com.
	client := playstore.NewWithParams(`developer's private key data`, `developer's email`)

	resp, err := client.Verify(`<package name>`, `<subscriptionID>`, `<purchaseToken>`)
	switch {
	case err != nil:
		log.Errof("error occured on api call: %s", err.Error())
		return
	case !resp.IsValidReceipt():
		log.Errof("purchase state is invalid")
		return
	case resp.IsExpired():
		log.Errof("subscription date is expired")
		return
	}

	// save iab data of valid receipt...
	switch {
	case resp.IsValidProduct():
		// for consumed item
	case resp.IsValidSubscription():
		// for subscription item
		// autoRenew := resp.AutoRenewing
		// expires := resp.ExpiryTimeMillis
	}
}

// cancel subscription
func cancel() {
	client := playstore.NewWithParams(`developer's private key data`, `developer's email`)

	// check currenct status
	resp, err := client.Verify(`<package name>`, `<subscriptionID>`, `<purchaseToken>`)
	switch {
	case err != nil:
		log.Errof("error occured on verify api call: %s", err.Error())
		return
	case !resp.IsActive():
		// already cancelled
		return
	}

	// execute cancel operation
	err = client.CancelSubscription(`<package name>`, `<subscriptionID>`, `<purchaseToken>`)
	if err != nil {
		log.Errof("error occured on cancel api call: %s", err.Error())
		return
	}

	// confirm cancel status
	resp, err = client.Verify(`<package name>`, `<subscriptionID>`, `<purchaseToken>`)
	switch {
	case err != nil:
		log.Errof("error occured on verify api call: %s", err.Error())
		return
	case !resp.IsValidSubscription():
		log.Errof("purchase state is invalid on cancel")
		return
	case resp.IsActive():
		log.Errof("subscription is still active")
		return
	}

	// successfully cancelled
}

Support

In App Purchase

This validator supports the receipt type for both iOS6 style or newer style.

In App Billing

This validator uses Version 3 API.

License

go-iap is licensed under the MIT.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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