18 Commits

Author SHA1 Message Date
sanjid133
96a12064d7 remove latest response 2020-02-17 14:30:34 +06:00
sanjid133
d8b160b5cb fix auto renew status 2020-02-11 20:27:55 +06:00
sanjid133
e811b02798 remove duplicate 2020-02-11 20:27:55 +06:00
sanjid133
5b94718573 status field not present in initial_buy 2020-02-11 20:27:55 +06:00
sanjid133
db9e8f1637 auto renew status string 2020-02-11 20:27:55 +06:00
sanjid133
2b7d6c1820 Add renewal field 2020-02-11 20:27:55 +06:00
sanjid133
d74d2cfd2c Verfiy latest receipt 2020-02-11 20:27:55 +06:00
Minhaz Ahmed Syrus
d5b4694461 Add missing subscription billing retry flag 2020-02-11 20:26:09 +06:00
Minhaz Ahmed Syrus
b0a4ee19ee Add missing notification verification fields 2020-02-11 20:26:09 +06:00
Minhaz Ahmed Syrus
202310d2c3 Add missing subscription billing retry flag 2020-02-11 20:26:09 +06:00
Minhaz Ahmed Syrus
45aa311b47 Add missing notification verification fields 2020-02-11 20:25:51 +06:00
sanjid133
51a2c89640 Add renewal field 2020-02-11 20:25:08 +06:00
sanjid133
36d117cd16 Verfiy latest receipt 2020-02-11 20:25:08 +06:00
sanjid133
e28611afcb Add missing is_upgrade field 2020-02-11 20:25:08 +06:00
Minhaz Ahmed Syrus
1fe1bd0f92 Add missing subscription billing retry flag 2020-02-11 20:25:08 +06:00
Minhaz Ahmed Syrus
f0ee201e43 Add missing notification verification fields 2020-02-11 20:24:39 +06:00
Minhaz Ahmed Syrus
312aa41817 Add missing subscription billing retry flag 2020-02-11 20:22:08 +06:00
Minhaz Ahmed Syrus
eb89375f2e Add missing notification verification fields 2020-02-11 20:22:08 +06:00
2 changed files with 20 additions and 15 deletions

View File

@@ -82,9 +82,14 @@ type SubscriptionNotification struct {
ExpirationIntent string `json:"expiration_intent"` ExpirationIntent string `json:"expiration_intent"`
// Auto renew info // Auto renew info
AutoRenewStatus string `json:"auto_renew_status"` // false or true AutoRenewStatus string `json:"auto_renew_status"` // false or true
AutoRenewProductID string `json:"auto_renew_product_id"` AutoRenewProductID string `json:"auto_renew_product_id"`
// HACK (msyrus): Separate Subscriptiton Notification from Notification verification response
Status int `json:"status,omitempty"`
Receipt NotificationReceipt `json:"recipt"`
SubscriptionRetryFlag string `json:"is_in_billing_retry_period,omitempty"`
// Posted if the notification_type is RENEWAL or INTERACTIVE_RENEWAL, and only if the renewal is successful. // Posted if the notification_type is RENEWAL or INTERACTIVE_RENEWAL, and only if the renewal is successful.
// Posted also if the notification_type is INITIAL_BUY. // Posted also if the notification_type is INITIAL_BUY.
// Not posted for notification_type CANCEL. // Not posted for notification_type CANCEL.

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
} }