Files
gocommon/iap/iap.go

174 lines
4.5 KiB
Go
Raw Permalink Normal View History

package iap
import (
"context"
b64 "encoding/base64"
"encoding/json"
"io/ioutil"
"net/http"
"os"
2024-05-17 09:52:12 +09:00
"repositories.action2quare.com/ayo/gocommon/logger"
"github.com/awa/go-iap/appstore/api"
"github.com/awa/go-iap/playstore"
)
var PlayStorePublicKey string
var PlayStorePackageName string
var PlayStoreClient *playstore.Client
type PlayStoreReceiptInfo struct {
OrderId string `json:"orderId"`
PackageName string `json:"packageName"`
ProductId string `json:"productId"`
PurchaseTime int `json:"purchaseTime"`
PurchaseState int `json:"purchaseState"`
PurchaseToken string `json:"purchaseToken"`
Quantity int `json:"quantity"`
Acknowledged bool `json:"acknowledged"`
}
func PlayStoreInit(packageName string, publickey string) {
jsonKey, err := ioutil.ReadFile("playstore-iap-kingdom.json")
if err != nil {
logger.Fatal(err)
return
}
PlayStoreClient, err = playstore.New(jsonKey)
if err != nil {
logger.Fatal(err)
return
}
PlayStorePublicKey = publickey
PlayStorePackageName = packageName
}
func PlayStoreVerifyReceipt(receptData string, signature string) (isVerified bool, receiptInfo PlayStoreReceiptInfo) {
var info PlayStoreReceiptInfo
uDec, _ := b64.URLEncoding.DecodeString(receptData)
bOk, err := playstore.VerifySignature(PlayStorePublicKey, []byte(uDec), signature)
if bOk == false || err != nil {
logger.Println("playstore - VerifySignature fail :" + err.Error())
return bOk, info
}
json.Unmarshal(uDec, &info)
return bOk, info
}
func PlayStoreVerifyProduct(info PlayStoreReceiptInfo) (bool, int, int) {
productPurchases, err := PlayStoreClient.VerifyProduct(context.Background(), PlayStorePackageName, info.ProductId, info.PurchaseToken)
if err != nil {
logger.Println("playstore - PlayStoreVerifyProduct fail :" + err.Error())
return false, -1, -1
}
// fmt.Println(productPurchases)
// fmt.Println("================")
// fmt.Println(productPurchases.PurchaseState)
// fmt.Println(productPurchases.ConsumptionState)
// fmt.Println("================")
return true, int(productPurchases.PurchaseState), int(productPurchases.ConsumptionState)
}
func PlayStoreConsumeProduct(info PlayStoreReceiptInfo) bool {
err := PlayStoreClient.ConsumeProduct(context.Background(), PlayStorePackageName, info.ProductId, info.PurchaseToken)
if err != nil {
logger.Error("playstore - PlayStoreConsumeProduct fail :" + err.Error())
return false
}
return true
}
var AppStoreClient *api.StoreClient
func AppStoreInit(keyPath string, configFilePath string) {
keyContentBytes, err := os.ReadFile(keyPath)
if err != nil {
logger.Fatal(err)
return
}
configBytes, err := os.ReadFile(configFilePath)
if err != nil {
logger.Fatal(err)
return
}
var configMap map[string]any
err = json.Unmarshal(configBytes, &configMap)
config := &api.StoreConfig{
KeyContent: keyContentBytes,
KeyID: configMap["KeyID"].(string),
BundleID: configMap["BundleID"].(string),
Issuer: configMap["Issuer"].(string),
Sandbox: configMap["Sandbox"].(bool),
}
AppStoreClient = api.NewStoreClient(config)
if config.Sandbox {
logger.Println("IPA - Appstore : Use Sandbox")
} else {
logger.Println("IPA - Appstore : Normal")
}
}
func AppStoreVerifyReceipt(transactionId string) (bool, *api.JWSTransaction) {
res, err := AppStoreClient.GetTransactionInfo(context.Background(), transactionId)
if err != nil {
logger.Error(err)
return false, nil
}
transaction, err := AppStoreClient.ParseSignedTransaction(res.SignedTransactionInfo)
if err != nil {
logger.Error(err)
return false, nil
}
if transaction.TransactionID != transactionId {
return false, nil
}
if len(transaction.OriginalTransactionId) == 0 {
return false, nil
}
return true, transaction
}
func AppStoreConsumeProduct(transaction *api.JWSTransaction) bool {
//https://developer.apple.com/documentation/appstoreserverapi/consumptionrequest
consumeReqBody := api.ConsumptionRequestBody{
AccountTenure: 0,
AppAccountToken: transaction.AppAccountToken,
ConsumptionStatus: 3,
CustomerConsented: true,
DeliveryStatus: 0,
LifetimeDollarsPurchased: 0,
LifetimeDollarsRefunded: 0,
Platform: 1,
PlayTime: 0,
SampleContentProvided: false,
UserStatus: 1,
}
statusCode, err := AppStoreClient.SendConsumptionInfo(context.Background(), transaction.OriginalTransactionId, consumeReqBody)
if statusCode != http.StatusAccepted {
return false
}
if err != nil {
logger.Error(err)
return false
}
return true
}