{"id":37095579,"url":"https://github.com/ivpn/go-iap","last_synced_at":"2026-01-14T11:46:49.078Z","repository":{"id":57530050,"uuid":"266996091","full_name":"ivpn/go-iap","owner":"ivpn","description":"go-iap verifies the purchase receipt via AppStore or GooglePlayStore","archived":false,"fork":true,"pushed_at":"2024-01-03T11:43:54.000Z","size":359,"stargazers_count":7,"open_issues_count":0,"forks_count":5,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-06-20T10:13:25.680Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"awa/go-iap","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ivpn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-05-26T09:09:22.000Z","updated_at":"2024-01-26T18:25:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ivpn/go-iap","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/ivpn/go-iap","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivpn%2Fgo-iap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivpn%2Fgo-iap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivpn%2Fgo-iap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivpn%2Fgo-iap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ivpn","download_url":"https://codeload.github.com/ivpn/go-iap/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivpn%2Fgo-iap/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28419257,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T10:47:48.104Z","status":"ssl_error","status_checked_at":"2026-01-14T10:46:19.031Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-14T11:46:48.600Z","updated_at":"2026-01-14T11:46:49.071Z","avatar_url":"https://github.com/ivpn.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"go-iap\n======\n\n![](https://img.shields.io/badge/golang-1.18+-blue.svg?style=flat)\n[![unit test](https://github.com/awa/go-iap/actions/workflows/unit_test.yml/badge.svg)](https://github.com/awa/go-iap/actions/workflows/unit_test.yml)\n\n\u003ego-iap verifies the purchase receipt via AppStore, GooglePlayStore or Amazon AppStore.\n\nCurrent API Documents:\n\n* AppStore: [![GoDoc](https://godoc.org/github.com/awa/go-iap/appstore?status.svg)](https://godoc.org/github.com/awa/go-iap/appstore)\n* AppStore Server API: [![GoDoc](https://godoc.org/github.com/awa/go-iap/appstore?status.svg)](https://godoc.org/github.com/awa/go-iap/appstore/api)\n* GooglePlay: [![GoDoc](https://godoc.org/github.com/awa/go-iap/playstore?status.svg)](https://godoc.org/github.com/awa/go-iap/playstore)\n* Amazon AppStore: [![GoDoc](https://godoc.org/github.com/awa/go-iap/amazon?status.svg)](https://godoc.org/github.com/awa/go-iap/amazon)\n* Huawei HMS: [![GoDoc](https://godoc.org/github.com/awa/go-iap/hms?status.svg)](https://godoc.org/github.com/awa/go-iap/hms)\n\n\n# Installation\n```\ngo get github.com/awa/go-iap/appstore\ngo get github.com/awa/go-iap/playstore\ngo get github.com/awa/go-iap/amazon\ngo get github.com/awa/go-iap/hms\n```\n\n\n# Quick Start\n\n### In App Purchase (via App Store)\n\n```go\nimport(\n    \"github.com/awa/go-iap/appstore\"\n)\n\nfunc main() {\n\tclient := appstore.New()\n\treq := appstore.IAPRequest{\n\t\tReceiptData: \"your receipt data encoded by base64\",\n\t}\n\tresp := \u0026appstore.IAPResponse{}\n\tctx := context.Background()\n\terr := client.Verify(ctx, req, resp)\n}\n```\n\n**Note**: The [verifyReceipt](https://developer.apple.com/documentation/appstorereceipts/verifyreceipt) API has been deprecated as of `5 Jun 2023`. Please use [App Store Server API](#in-app-store-server-api) instead.\n\n### In App Billing (via GooglePlay)\n\n```go\nimport(\n    \"github.com/awa/go-iap/playstore\"\n)\n\nfunc main() {\n\t// You need to prepare a public key for your Android app's in app billing\n\t// at https://console.developers.google.com.\n\tjsonKey, err := ioutil.ReadFile(\"jsonKey.json\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tclient := playstore.New(jsonKey)\n\tctx := context.Background()\n\tresp, err := client.VerifySubscription(ctx, \"package\", \"subscriptionID\", \"purchaseToken\")\n}\n```\n\n### In App Purchase (via Amazon App Store)\n\n```go\nimport(\n    \"github.com/awa/go-iap/amazon\"\n)\n\nfunc main() {\n\tclient := amazon.New(\"developerSecret\")\n\n\tctx := context.Background()\n\tresp, err := client.Verify(ctx, \"userID\", \"receiptID\")\n}\n```\n\n### In App Purchase (via Huawei Mobile Services)\n\n```go\nimport(\n    \"github.com/awa/go-iap/hms\"\n)\n\nfunc main() {\n\t// If \"orderSiteURL\" and/or \"subscriptionSiteURL\" are empty,\n\t// they will be default to AppTouch German.\n\t// Please refer to https://developer.huawei.com/consumer/en/doc/HMSCore-References-V5/api-common-statement-0000001050986127-V5 for details.\n\tclient := hms.New(\"clientID\", \"clientSecret\", \"orderSiteURL\", \"subscriptionSiteURL\")\n\tctx := context.Background()\n\tresp, err := client.VerifySubscription(ctx, \"purchaseToken\", \"subscriptionID\", 1)\n}\n```\n\n### In App Store Server API\n\n- GetTransactionInfo\n\n```go\nimport(\n\t\"github.com/awa/go-iap/appstore/api\"\n)\n\n//  For generate key file and download it, please refer to https://developer.apple.com/documentation/appstoreserverapi/creating_api_keys_to_use_with_the_app_store_server_api\nconst ACCOUNTPRIVATEKEY = `\n    -----BEGIN PRIVATE KEY-----\n    FAKEACCOUNTKEYBASE64FORMAT\n    -----END PRIVATE KEY-----\n    `\nfunc main() {\n\tc := \u0026api.StoreConfig{\n\t\tKeyContent: []byte(ACCOUNTPRIVATEKEY),  // Loads a .p8 certificate\n\t\tKeyID:      \"FAKEKEYID\",                // Your private key ID from App Store Connect (Ex: 2X9R4HXF34)\n\t\tBundleID:   \"fake.bundle.id\",           // Your app’s bundle ID\n\t\tIssuer:     \"xxxxx-xx-xx-xx-xxxxxxxxxx\",// Your issuer ID from the Keys page in App Store Connect (Ex: \"57246542-96fe-1a63-e053-0824d011072a\")\n\t\tSandbox:    false,                      // default is Production\n\t}\n\ttransactionId := \"FAKETRANSACTIONID\"\n\ta := api.NewStoreClient(c)\n\tctx := context.Background()\n\tresponse, err := a.GetTransactionInfo(ctx, transactionId)\n\n\ttransantion, err := a.ParseSignedTransaction(response.SignedTransactionInfo)\n\tif err != nil {\n\t    // error handling\n\t}\n\n\tif transaction.TransactionId == transactionId {\n\t\t// the transaction is valid\n\t}\n}\n```\n\n- GetTransactionHistory\n\n```go\nimport(\n\t\"github.com/awa/go-iap/appstore/api\"\n)\n\n//  For generate key file and download it, please refer to https://developer.apple.com/documentation/appstoreserverapi/creating_api_keys_to_use_with_the_app_store_server_api\nconst ACCOUNTPRIVATEKEY = `\n    -----BEGIN PRIVATE KEY-----\n    FAKEACCOUNTKEYBASE64FORMAT\n    -----END PRIVATE KEY-----\n    `\nfunc main() {\n\tc := \u0026api.StoreConfig{\n\t\tKeyContent: []byte(ACCOUNTPRIVATEKEY),  // Loads a .p8 certificate\n\t\tKeyID:      \"FAKEKEYID\",                // Your private key ID from App Store Connect (Ex: 2X9R4HXF34)\n\t\tBundleID:   \"fake.bundle.id\",           // Your app’s bundle ID\n\t\tIssuer:     \"xxxxx-xx-xx-xx-xxxxxxxxxx\",// Your issuer ID from the Keys page in App Store Connect (Ex: \"57246542-96fe-1a63-e053-0824d011072a\")\n\t\tSandbox:    false,                      // default is Production\n\t}\n\toriginalTransactionId := \"FAKETRANSACTIONID\"\n\ta := api.NewStoreClient(c)\n\tquery := \u0026url.Values{}\n\tquery.Set(\"productType\", \"AUTO_RENEWABLE\")\n\tquery.Set(\"productType\", \"NON_CONSUMABLE\")\n\tctx := context.Background()\n\tresponses, err := a.GetTransactionHistory(ctx, originalTransactionId, query)\n\n\tfor _, response := range responses {\n\t\ttransantions, err := a.ParseSignedTransactions(response.SignedTransactions)\n\t}\n}\n```\n- Error handling\n  - handler error per [apple store server api error](https://developer.apple.com/documentation/appstoreserverapi/error_codes) document\n  - [error definition](./appstore/api/error.go)\n\n\n### Parse Notification from App Store\n\n```go\nimport (\n\t\"github.com/awa/go-iap/appstore\"\n\t\"github.com/golang-jwt/jwt/v4\"\n)\n\nfunc main() {\n\ttokenStr := \"SignedRenewalInfo Encode String\" // or SignedTransactionInfo string\n\ttoken := jwt.Token{}\n\tclient := appstore.New()\n\terr := client.ParseNotificationV2(tokenStr, \u0026token)\n\n\tclaims, ok := token.Claims.(jwt.MapClaims)\n\tfor key, val := range claims {\n\t\tfmt.Printf(\"Key: %v, value: %v\\n\", key, val) // key value of SignedRenewalInfo\n\t}\n}\n```\n\n# ToDo\n- [x] Validator for In App Purchase Receipt (AppStore)\n- [x] Validator for Subscription token (GooglePlay)\n- [x] Validator for Purchase Product token (GooglePlay)\n- [ ] More Tests\n\n\n# Support\n\n### In App Purchase\nThis validator supports the receipt type for iOS7 or above.\n\n### In App Billing\nThis validator uses [Version 3 API](http://developer.android.com/google/play/billing/api.html).\n\n### In App Purchase (Amazon)\nThis validator uses [RVS for IAP v2.0](https://developer.amazon.com/public/apis/earn/in-app-purchasing/docs-v2/verifying-receipts-in-iap-2.0).\n\n### In App Purchase (HMS)\nThis validator uses [Version 2 API](https://developer.huawei.com/consumer/en/doc/HMSCore-References-V5/api-common-statement-0000001050986127-V5).\n\n### In App Store Server API\nThis validator uses [Version 1.0+](https://developer.apple.com/documentation/appstoreserverapi)\n\n# License\ngo-iap is licensed under the MIT.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivpn%2Fgo-iap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fivpn%2Fgo-iap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivpn%2Fgo-iap/lists"}