Verfiy latest receipt

This commit is contained in:
sanjid133
2019-08-06 17:22:41 +06:00
parent c992b9705b
commit ee59170931
2 changed files with 24 additions and 14 deletions

View File

@@ -138,6 +138,16 @@ type (
IsRetryable bool `json:"is-retryable,omitempty"` IsRetryable bool `json:"is-retryable,omitempty"`
} }
// The IAPLatestResponse type has the response properties
// If you use latest_receipt as token to verify, response should be like following struct
IAPLatestResponse struct {
Status int `json:"status"`
Receipt InApp `json:"receipt"`
LatestReceiptInfo InApp `json:"latest_receipt_info,omitempty"`
LatestExpiredReceiptInfo InApp `json:"latest_expired_receipt_info,omitempty"`
LatestReceipt string `json:"latest_receipt,omitempty"`
}
// The HttpStatusResponse struct contains the status code returned by the store // The HttpStatusResponse struct contains the status code returned by the store
// Used as a workaround to detect when to hit the production appstore or sandbox appstore regardless of receipt type // Used as a workaround to detect when to hit the production appstore or sandbox appstore regardless of receipt type
StatusResponse struct { StatusResponse struct {

View File

@@ -96,64 +96,64 @@ func NewWithClient(client *http.Client) *Client {
} }
// Verify sends receipts and gets validation result // Verify sends receipts and gets validation result
func (c *Client) Verify(ctx context.Context, reqBody IAPRequest, result interface{}) error { func (c *Client) Verify(ctx context.Context, reqBody IAPRequest, result interface{}) (Environment, error) {
b := new(bytes.Buffer) b := new(bytes.Buffer)
if err := json.NewEncoder(b).Encode(reqBody); err != nil { if err := json.NewEncoder(b).Encode(reqBody); err != nil {
return err return "", err
} }
req, err := http.NewRequest("POST", c.ProductionURL, b) req, err := http.NewRequest("POST", c.ProductionURL, b)
if err != nil { if err != nil {
return err return "", err
} }
req.Header.Set("Content-Type", ContentType) req.Header.Set("Content-Type", ContentType)
req = req.WithContext(ctx) req = req.WithContext(ctx)
resp, err := c.httpCli.Do(req) resp, err := c.httpCli.Do(req)
if err != nil { if err != nil {
return err return "", err
} }
defer resp.Body.Close() defer resp.Body.Close()
return c.parseResponse(resp, result, ctx, reqBody) return c.parseResponse(resp, result, ctx, reqBody)
} }
func (c *Client) parseResponse(resp *http.Response, result interface{}, ctx context.Context, reqBody IAPRequest) error { func (c *Client) parseResponse(resp *http.Response, result interface{}, ctx context.Context, reqBody IAPRequest) (Environment, error) {
// Read the body now so that we can unmarshal it twice // Read the body now so that we can unmarshal it twice
buf, err := ioutil.ReadAll(resp.Body) buf, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return err return "", err
} }
err = json.Unmarshal(buf, &result) err = json.Unmarshal(buf, &result)
if err != nil { if err != nil {
return err return "", err
} }
// https://developer.apple.com/library/content/technotes/tn2413/_index.html#//apple_ref/doc/uid/DTS40016228-CH1-RECEIPTURL // https://developer.apple.com/library/content/technotes/tn2413/_index.html#//apple_ref/doc/uid/DTS40016228-CH1-RECEIPTURL
var r StatusResponse var r StatusResponse
err = json.Unmarshal(buf, &r) err = json.Unmarshal(buf, &r)
if err != nil { if err != nil {
return err return "", err
} }
if r.Status == 21007 { if r.Status == 21007 {
b := new(bytes.Buffer) b := new(bytes.Buffer)
if err := json.NewEncoder(b).Encode(reqBody); err != nil { if err := json.NewEncoder(b).Encode(reqBody); err != nil {
return err return "", err
} }
req, err := http.NewRequest("POST", c.SandboxURL, b) req, err := http.NewRequest("POST", c.SandboxURL, b)
if err != nil { if err != nil {
return err return "", err
} }
req.Header.Set("Content-Type", ContentType) req.Header.Set("Content-Type", ContentType)
req = req.WithContext(ctx) req = req.WithContext(ctx)
resp, err := c.httpCli.Do(req) resp, err := c.httpCli.Do(req)
if err != nil { if err != nil {
return err return "", err
} }
defer resp.Body.Close() defer resp.Body.Close()
// 21007 is found when the receipt is from the test environment
return json.NewDecoder(resp.Body).Decode(result) return Sandbox, json.NewDecoder(resp.Body).Decode(result)
} }
return nil return Production, nil
} }