forked from mhemmings/revenuecat
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
22 changed files
with
1,040 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
name: Test | ||
|
||
on: [push, pull_request] | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-20.04 | ||
strategy: | ||
matrix: | ||
go-version: [1.13.x, 1.14.x, 1.15.x] | ||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v2 | ||
- name: Setup Go | ||
uses: actions/setup-go@v2 | ||
with: | ||
go-version: ${{ matrix.go-version }} | ||
- name: go vet | ||
run: go vet ./... | ||
- name: go test | ||
run: go test -v ./... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2020 Mark Hemmings | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,135 @@ | ||
# revenuecat | ||
# RevenueCat | ||
|
||
[![PkgGoDev](https://pkg.go.dev/badge/pkg.go.dev/github.com/mhemmings/revenuecat)](https://pkg.go.dev/pkg.go.dev/github.com/mhemmings/revenuecat) | ||
[![Test](https://github.com/mhemmings/revenuecat/workflows/Test/badge.svg?branch=master)](https://github.com/mhemmings/revenuecat/actions?query=workflow%3ATest) | ||
|
||
Go package for interacting with the [RevenueCat API](https://docs.revenuecat.com/reference). | ||
|
||
## Usage | ||
|
||
### Example | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/mhemmings/revenuecat" | ||
) | ||
|
||
func main() { | ||
rc := revenuecat.New("apikey") | ||
sub, _ := rc.GetSubscriber("123") | ||
entitled := sub.IsEntitledTo("premium") | ||
|
||
fmt.Println("user entitled: %t", entitled) | ||
} | ||
``` | ||
|
||
### Documentation | ||
|
||
For full documentation, see [pkg.go.dev/github.com/mhemmings/revenuecat](https://pkg.go.dev/github.com/mhemmings/revenuecat) | ||
|
||
|
||
#### func (*Client) AddUserAttribution | ||
|
||
```go | ||
func (c *Client) AddUserAttribution(userID string, network Network, data AttributionData) error | ||
``` | ||
AddUserAttribution attaches attribution data to a subscriber from specific | ||
supported networks. https://docs.revenuecat.com/reference#subscribersattribution | ||
|
||
#### func (*Client) CreatePurchase | ||
|
||
```go | ||
func (c *Client) CreatePurchase(userID string, receipt string, opt *CreatePurchaseOptions) (Subscriber, error) | ||
``` | ||
CreatePurchase records a purchase for a user from iOS, Android, or Stripe and | ||
will create a user if they don't already exist. | ||
https://docs.revenuecat.com/reference#receipts | ||
|
||
#### func (*Client) DeferGoogleSubscription | ||
|
||
```go | ||
func (c *Client) DeferGoogleSubscription(userID string, id string, nextExpiry time.Time) (Subscriber, error) | ||
``` | ||
DeferGoogleSubscription defers the purchase of a Google Subscription to a later | ||
date. https://docs.revenuecat.com/reference#defer-a-google-subscription | ||
|
||
#### func (*Client) DeleteOfferingOverride | ||
|
||
```go | ||
func (c *Client) DeleteOfferingOverride(userID string) (Subscriber, error) | ||
``` | ||
DeleteOfferingOverride reset the offering overrides back to the current offering | ||
for a specific user. | ||
https://docs.revenuecat.com/reference#delete-offering-override | ||
|
||
#### func (*Client) DeleteSubscriber | ||
|
||
```go | ||
func (c *Client) DeleteSubscriber(userID string) error | ||
``` | ||
DeleteSubscriber permanently deletes a subscriber. | ||
https://docs.revenuecat.com/reference#subscribersapp_user_id | ||
|
||
#### func (*Client) GetSubscriber | ||
|
||
```go | ||
func (c *Client) GetSubscriber(userID string) (Subscriber, error) | ||
``` | ||
GetSubscriber gets the latest subscriber info or creates one if it doesn't | ||
exist. https://docs.revenuecat.com/reference#subscribers | ||
|
||
#### func (*Client) GetSubscriberWithPlatform | ||
|
||
```go | ||
func (c *Client) GetSubscriberWithPlatform(userID string, platform string) (Subscriber, error) | ||
``` | ||
GetSubscriberWithPlatform gets the latest subscriber info or creates one if it | ||
doesn't exist, updating the subscriber record's last_seen value for the platform | ||
provided. https://docs.revenuecat.com/reference#subscribers | ||
|
||
#### func (*Client) GrantEntitlement | ||
|
||
```go | ||
func (c *Client) GrantEntitlement(userID string, id string, duration Duration, startTime time.Time) (Subscriber, error) | ||
``` | ||
GrantEntitlement grants a user a promotional entitlement. | ||
https://docs.revenuecat.com/reference#grant-a-promotional-entitlement | ||
|
||
#### func (*Client) OverrideOffering | ||
|
||
```go | ||
func (c *Client) OverrideOffering(userID string, offeringUUID string) (Subscriber, error) | ||
``` | ||
OverrideOffering overrides the current Offering for a specific user. | ||
https://docs.revenuecat.com/reference#override-offering | ||
|
||
#### func (*Client) RefundGoogleSubscription | ||
|
||
```go | ||
func (c *Client) RefundGoogleSubscription(userID string, id string) (Subscriber, error) | ||
``` | ||
RefundGoogleSubscription immediately revokes access to a Google Subscription and | ||
issues a refund for the last purchase. | ||
https://docs.revenuecat.com/reference#revoke-a-google-subscription | ||
|
||
#### func (*Client) RevokeEntitlement | ||
|
||
```go | ||
func (c *Client) RevokeEntitlement(userID string, id string) (Subscriber, error) | ||
``` | ||
RevokeEntitlement revokes all promotional entitlements for a given entitlement | ||
identifier and app user ID. | ||
https://docs.revenuecat.com/reference#revoke-promotional-entitlements | ||
|
||
#### func (*Client) UpdateSubscriberAttributes | ||
|
||
```go | ||
func (c *Client) UpdateSubscriberAttributes(userID string, attributes map[string]SubscriberAttribute) error | ||
``` | ||
UpdateSubscriberAttributes updates subscriber attributes for a user. | ||
https://docs.revenuecat.com/reference#update-subscriber-attributes | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package revenuecat | ||
|
||
// Network represents a predefined attribution channel. | ||
type Network int | ||
|
||
// https://docs.revenuecat.com/reference#attribution-source-network-codes | ||
const ( | ||
AppleSearchAds Network = iota | ||
Adjust | ||
AppsFlyer | ||
Branch | ||
Tenjin | ||
) | ||
|
||
// AttributionData holds the identifier value for either the App Store or Play Services. | ||
type AttributionData struct { | ||
IDFA string `json:"rc_idfa,omitempty"` | ||
PlayServicesID string `json:"rc_gps_adid,omitempty"` | ||
} | ||
|
||
// AddUserAttribution attaches attribution data to a subscriber from specific supported networks. | ||
// https://docs.revenuecat.com/reference#subscribersattribution | ||
func (c *Client) AddUserAttribution(userID string, network Network, data AttributionData) error { | ||
var resp struct { | ||
Subscriber Subscriber `json:"subscriber"` | ||
} | ||
|
||
req := struct { | ||
Data AttributionData `json:"data"` | ||
Network Network `json:"network"` | ||
}{ | ||
Data: data, | ||
Network: network, | ||
} | ||
|
||
return c.call("POST", "subscribers/"+userID+"/attribution", req, "", &resp) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package revenuecat | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func TestAddUserAttribution(t *testing.T) { | ||
cl := newMockClient(t, 200, nil, nil) | ||
rc := New("apikey") | ||
rc.http = cl | ||
|
||
err := rc.AddUserAttribution("123", Facebook, AttributionData{IDFA: "test"}) | ||
if err != nil { | ||
t.Errorf("error: %v", err) | ||
} | ||
|
||
cl.expectMethod(t, "POST") | ||
cl.expectPath(t, "/v1/subscribers/123/attribution") | ||
cl.expectBody(t, `{"data":{"rc_idfa":"test"},"network":5}`) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package revenuecat | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"net/http" | ||
"time" | ||
) | ||
|
||
// Client makes authorized calls to the RevenueCat API. | ||
type Client struct { | ||
apiKey string | ||
apiURL string | ||
http doer | ||
} | ||
|
||
type doer interface { | ||
Do(req *http.Request) (*http.Response, error) | ||
} | ||
|
||
// New returns a new *Client for the provided API key. | ||
// For more information on authentication, see https://docs.revenuecat.com/docs/authentication. | ||
func New(apiKey string) *Client { | ||
return &Client{ | ||
apiKey: apiKey, | ||
apiURL: "https://api.revenuecat.com/v1/", | ||
http: &http.Client{ | ||
// Set a long timeout here since calls to Apple are probably invloved. | ||
Timeout: 10 * time.Second, | ||
}, | ||
} | ||
} | ||
|
||
func (c *Client) call(method, path string, reqBody interface{}, platform string, respBody interface{}) error { | ||
var reqBodyJSON io.Reader | ||
if reqBody != nil { | ||
js, err := json.Marshal(reqBody) | ||
if err != nil { | ||
return fmt.Errorf("error marshaling request body: %v", err) | ||
} | ||
reqBodyJSON = bytes.NewBuffer(js) | ||
} | ||
req, err := http.NewRequest(method, c.apiURL+path, reqBodyJSON) | ||
if err != nil { | ||
return fmt.Errorf("error creating request: %v", err) | ||
} | ||
req.Header.Add("Authorization", "Bearer "+c.apiKey) | ||
req.Header.Add("Content-Type", "application/json") | ||
if platform != "" { | ||
req.Header.Add("X-Platform", "ios") | ||
} | ||
|
||
resp, err := c.http.Do(req) | ||
if err != nil { | ||
return fmt.Errorf("error making request: %v", err) | ||
} | ||
defer resp.Body.Close() | ||
if resp.StatusCode >= 400 { | ||
var errResp Error | ||
err = json.NewDecoder(resp.Body).Decode(&errResp) | ||
if err != nil { | ||
return err | ||
} | ||
return errResp | ||
} | ||
if respBody == nil { | ||
// Expecting an empty body. | ||
return nil | ||
} | ||
err = json.NewDecoder(resp.Body).Decode(respBody) | ||
if err != nil { | ||
return fmt.Errorf("error decoding response: %v", err) | ||
} | ||
return nil | ||
} |
Oops, something went wrong.